Commit 6fe88955 authored by Vincent Boisselle's avatar Vincent Boisselle Committed by Commit Bot

Feature to locally auto-dismiss the notice card in Feed V2

Bug: 1146458
Change-Id: Ibca4559552d991667ea5043687845e845b251db1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2527719
Commit-Queue: Vincent Boisselle <vincb@google.com>
Reviewed-by: default avatarDan H <harringtond@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826640}
parent 2bd8a90b
...@@ -46,18 +46,18 @@ extern const char kHostOverrideBlessNonce[]; ...@@ -46,18 +46,18 @@ extern const char kHostOverrideBlessNonce[];
// to enable the upload of click and view actions in the feed with the notice // to enable the upload of click and view actions in the feed with the notice
// card when using the feature kInterestFeedConditionalClickAndViewActionUpload. // card when using the feature kInterestFeedConditionalClickAndViewActionUpload.
// This is for when the privacy notice card is at the second position in the // This is for when the privacy notice card is at the second position in the
// feed. Currently only used in V1. // feed.
extern const char kHasReachedClickAndViewActionsUploadConditions[]; extern const char kHasReachedClickAndViewActionsUploadConditions[];
// The pref name for the bit that determines whether the notice card was present // The pref name for the bit that determines whether the notice card was present
// in the feed in the last fetch of content. The notice card is considered as // in the feed in the last fetch of content. The notice card is considered as
// present by default to make sure that the upload of click and view actions // present by default to make sure that the upload of click and view actions
// doesn't take place when the notice card is present but has not yet been // doesn't take place when the notice card is present but has not yet been
// detected. Currently only used in V1. // detected.
extern const char kLastFetchHadNoticeCard[]; extern const char kLastFetchHadNoticeCard[];
// The pref name for the bit that determines whether the last refresh request // The pref name for the bit that determines whether the last refresh request
// was signed in. // was signed in. Currently only used in V1.
extern const char kLastRefreshWasSignedIn[]; extern const char kLastRefreshWasSignedIn[];
// The pref name for the counter for the number of views on the notice card. // The pref name for the counter for the number of views on the notice card.
......
...@@ -29,6 +29,7 @@ proto_library("proto_v2") { ...@@ -29,6 +29,7 @@ proto_library("proto_v2") {
"v2/wire/action_payload.proto", "v2/wire/action_payload.proto",
"v2/wire/capability.proto", "v2/wire/capability.proto",
"v2/wire/chrome_feed_response_metadata.proto", "v2/wire/chrome_feed_response_metadata.proto",
"v2/wire/chrome_fulfillment_info.proto",
"v2/wire/client_info.proto", "v2/wire/client_info.proto",
"v2/wire/consistency_token.proto", "v2/wire/consistency_token.proto",
"v2/wire/content_id.proto", "v2/wire/content_id.proto",
......
syntax = "proto2";
package feedwire;
option optimize_for = LITE_RUNTIME;
// Information on how to do content fulfillment for Chrome.
message ChromeFulfillmentInfo {
// Whether the notice card has already been acknowledged by the user based on
// their views and clicks on the card. This is different from when the user
// explicitly dismiss the notice card by touching the button.
optional bool notice_card_acknowledged = 1;
}
...@@ -8,6 +8,7 @@ package feedwire; ...@@ -8,6 +8,7 @@ package feedwire;
option optimize_for = LITE_RUNTIME; option optimize_for = LITE_RUNTIME;
import "components/feed/core/proto/v2/wire/chrome_fulfillment_info.proto";
import "components/feed/core/proto/v2/wire/token.proto"; import "components/feed/core/proto/v2/wire/token.proto";
message FeedQuery { message FeedQuery {
...@@ -48,5 +49,8 @@ message FeedQuery { ...@@ -48,5 +49,8 @@ message FeedQuery {
Tokens in_place_update_tokens = 5; Tokens in_place_update_tokens = 5;
} }
// Information on how to do content fulfillment for Chrome.
optional ChromeFulfillmentInfo chrome_fulfillment_info = 341477699;
reserved 2; reserved 2;
} }
...@@ -27,6 +27,8 @@ source_set("feed_core_v2") { ...@@ -27,6 +27,8 @@ source_set("feed_core_v2") {
"image_fetcher.h", "image_fetcher.h",
"metrics_reporter.cc", "metrics_reporter.cc",
"metrics_reporter.h", "metrics_reporter.h",
"notice_card_tracker.cc",
"notice_card_tracker.h",
"offline_page_spy.cc", "offline_page_spy.cc",
"offline_page_spy.h", "offline_page_spy.h",
"prefs.cc", "prefs.cc",
...@@ -106,6 +108,7 @@ source_set("core_unit_tests") { ...@@ -106,6 +108,7 @@ source_set("core_unit_tests") {
"feed_stream_unittest.cc", "feed_stream_unittest.cc",
"image_fetcher_unittest.cc", "image_fetcher_unittest.cc",
"metrics_reporter_unittest.cc", "metrics_reporter_unittest.cc",
"notice_card_tracker_unittest.cc",
"proto_util_unittest.cc", "proto_util_unittest.cc",
"protocol_translator_unittest.cc", "protocol_translator_unittest.cc",
"public/feed_service_unittest.cc", "public/feed_service_unittest.cc",
......
...@@ -157,7 +157,8 @@ FeedStream::FeedStream(RefreshTaskScheduler* refresh_task_scheduler, ...@@ -157,7 +157,8 @@ FeedStream::FeedStream(RefreshTaskScheduler* refresh_task_scheduler,
chrome_info_(chrome_info), chrome_info_(chrome_info),
task_queue_(this), task_queue_(this),
request_throttler_(profile_prefs, clock), request_throttler_(profile_prefs, clock),
metadata_(feed_store) { metadata_(feed_store),
notice_card_tracker_(profile_prefs) {
static WireResponseTranslator default_translator; static WireResponseTranslator default_translator;
wire_response_translator_ = &default_translator; wire_response_translator_ = &default_translator;
...@@ -576,6 +577,8 @@ RequestMetadata FeedStream::GetRequestMetadata() { ...@@ -576,6 +577,8 @@ RequestMetadata FeedStream::GetRequestMetadata() {
result.display_metrics = delegate_->GetDisplayMetrics(); result.display_metrics = delegate_->GetDisplayMetrics();
result.language_tag = delegate_->GetLanguageTag(); result.language_tag = delegate_->GetLanguageTag();
result.client_instance_id = GetClientInstanceId(); result.client_instance_id = GetClientInstanceId();
result.notice_card_acknowledged =
notice_card_tracker_.HasAcknowledgedNoticeCard();
return result; return result;
} }
...@@ -707,12 +710,12 @@ void FeedStream::UnloadModel() { ...@@ -707,12 +710,12 @@ void FeedStream::UnloadModel() {
surface_updater_->SetModel(nullptr); surface_updater_->SetModel(nullptr);
model_.reset(); model_.reset();
} }
void FeedStream::ReportOpenAction(const std::string& slice_id) { void FeedStream::ReportOpenAction(const std::string& slice_id) {
int index = surface_updater_->GetSliceIndexFromSliceId(slice_id); int index = surface_updater_->GetSliceIndexFromSliceId(slice_id);
if (index < 0) if (index < 0)
index = MetricsReporter::kUnknownCardIndex; index = MetricsReporter::kUnknownCardIndex;
metrics_reporter_->OpenAction(index); metrics_reporter_->OpenAction(index);
notice_card_tracker_.OnOpenAction(index);
} }
void FeedStream::ReportOpenVisitComplete(base::TimeDelta visit_time) { void FeedStream::ReportOpenVisitComplete(base::TimeDelta visit_time) {
metrics_reporter_->OpenVisitComplete(visit_time); metrics_reporter_->OpenVisitComplete(visit_time);
...@@ -722,6 +725,7 @@ void FeedStream::ReportOpenInNewTabAction(const std::string& slice_id) { ...@@ -722,6 +725,7 @@ void FeedStream::ReportOpenInNewTabAction(const std::string& slice_id) {
if (index < 0) if (index < 0)
index = MetricsReporter::kUnknownCardIndex; index = MetricsReporter::kUnknownCardIndex;
metrics_reporter_->OpenInNewTabAction(index); metrics_reporter_->OpenInNewTabAction(index);
notice_card_tracker_.OnOpenAction(index);
} }
void FeedStream::ReportOpenInNewIncognitoTabAction() { void FeedStream::ReportOpenInNewIncognitoTabAction() {
metrics_reporter_->OpenInNewIncognitoTabAction(); metrics_reporter_->OpenInNewIncognitoTabAction();
...@@ -731,6 +735,7 @@ void FeedStream::ReportSliceViewed(SurfaceId surface_id, ...@@ -731,6 +735,7 @@ void FeedStream::ReportSliceViewed(SurfaceId surface_id,
int index = surface_updater_->GetSliceIndexFromSliceId(slice_id); int index = surface_updater_->GetSliceIndexFromSliceId(slice_id);
if (index >= 0) { if (index >= 0) {
UpdateShownSlicesUploadCondition(index); UpdateShownSlicesUploadCondition(index);
notice_card_tracker_.OnSliceViewed(index);
metrics_reporter_->ContentSliceViewed(surface_id, index); metrics_reporter_->ContentSliceViewed(surface_id, index);
} }
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/feed/core/proto/v2/ui.pb.h" #include "components/feed/core/proto/v2/ui.pb.h"
#include "components/feed/core/proto/v2/wire/response.pb.h" #include "components/feed/core/proto/v2/wire/response.pb.h"
#include "components/feed/core/v2/enums.h" #include "components/feed/core/v2/enums.h"
#include "components/feed/core/v2/notice_card_tracker.h"
#include "components/feed/core/v2/protocol_translator.h" #include "components/feed/core/v2/protocol_translator.h"
#include "components/feed/core/v2/public/feed_stream_api.h" #include "components/feed/core/v2/public/feed_stream_api.h"
#include "components/feed/core/v2/request_throttler.h" #include "components/feed/core/v2/request_throttler.h"
...@@ -361,6 +362,8 @@ class FeedStream : public FeedStreamApi, ...@@ -361,6 +362,8 @@ class FeedStream : public FeedStreamApi,
// internals page for debugging purpose. // internals page for debugging purpose.
feedui::StreamUpdate forced_stream_update_for_debugging_; feedui::StreamUpdate forced_stream_update_for_debugging_;
NoticeCardTracker notice_card_tracker_;
base::WeakPtrFactory<FeedStream> weak_ptr_factory_{this}; base::WeakPtrFactory<FeedStream> weak_ptr_factory_{this};
}; };
......
...@@ -574,10 +574,7 @@ class FeedStreamTest : public testing::Test, public FeedStream::Delegate { ...@@ -574,10 +574,7 @@ class FeedStreamTest : public testing::Test, public FeedStream::Delegate {
CreateStream(); CreateStream();
} }
virtual void SetupFeatures() { virtual void SetupFeatures() {}
scoped_feature_list_.InitAndDisableFeature(
feed::kInterestFeedV2ClicksAndViewsConditionalUpload);
}
void TearDown() override { void TearDown() override {
// Ensure the task queue can return to idle. Failure to do so may be due // Ensure the task queue can return to idle. Failure to do so may be due
...@@ -2380,5 +2377,38 @@ TEST_F(FeedStreamTest, SendsClientInstanceId) { ...@@ -2380,5 +2377,38 @@ TEST_F(FeedStreamTest, SendsClientInstanceId) {
ASSERT_NE(first_instance_id, new_instance_id); ASSERT_NE(first_instance_id, new_instance_id);
} }
TEST_F(FeedStreamTest, LoadStreamSendsNoticeCardAcknowledgement) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
feed::kInterestFeedNoticeCardAutoDismiss);
store_->OverwriteStream(MakeTypicalInitialModelState(), base::DoNothing());
TestSurface surface(stream_.get());
WaitForIdleTaskQueue();
// Generate 3 view actions and 1 click action to trigger the acknowledgement
// of the notice card.
const int notice_card_index = 0;
std::string slice_id =
surface.initial_state->updated_slices(notice_card_index)
.slice()
.slice_id();
stream_->ReportSliceViewed(surface.GetSurfaceId(), slice_id);
stream_->ReportSliceViewed(surface.GetSurfaceId(), slice_id);
stream_->ReportSliceViewed(surface.GetSurfaceId(), slice_id);
stream_->ReportOpenAction(slice_id);
response_translator_.InjectResponse(MakeTypicalInitialModelState());
refresh_scheduler_.Clear();
stream_->UnloadModel();
stream_->ExecuteRefreshTask();
WaitForIdleTaskQueue();
EXPECT_TRUE(network_.query_request_sent->feed_request()
.feed_query()
.chrome_fulfillment_info()
.notice_card_acknowledged());
}
} // namespace } // namespace
} // namespace feed } // namespace feed
// Copyright 2020 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 "components/feed/core/v2/notice_card_tracker.h"
#include "components/feed/core/v2/prefs.h"
#include "components/feed/feed_feature_list.h"
#include "components/prefs/pref_service.h"
namespace feed {
namespace {
int GetNoticeCardIndex() {
// Infer that the notice card is at the 2nd position when the feature related
// to putting the notice card at the second position is enabled.
if (base::FeatureList::IsEnabled(
feed::kInterestFeedV2ClicksAndViewsConditionalUpload)) {
return 1;
}
return 0;
}
} // namespace
NoticeCardTracker::NoticeCardTracker(PrefService* profile_prefs)
: profile_prefs_(profile_prefs) {
DCHECK(profile_prefs_);
}
void NoticeCardTracker::OnSliceViewed(int index) {
MaybeUpdateNoticeCardViewsCount(index);
}
void NoticeCardTracker::OnOpenAction(int index) {
MaybeUpdateNoticeCardClicksCount(index);
}
bool NoticeCardTracker::HasAcknowledgedNoticeCard() {
constexpr char kNoticeCardViewsCountThresholdParamName[] =
"notice-card-views-count-threshold";
constexpr char kNoticeCardClicksCountThresholdParamName[] =
"notice-card-clicks-count-threshold";
if (!base::FeatureList::IsEnabled(feed::kInterestFeedNoticeCardAutoDismiss))
return false;
int views_count_threshold = base::GetFieldTrialParamByFeatureAsInt(
feed::kInterestFeedNoticeCardAutoDismiss,
kNoticeCardViewsCountThresholdParamName, 3);
int views_count = prefs::GetNoticeCardViewsCount(*profile_prefs_);
if (views_count >= views_count_threshold) {
return true;
}
int clicks_count_threshold = base::GetFieldTrialParamByFeatureAsInt(
feed::kInterestFeedNoticeCardAutoDismiss,
kNoticeCardClicksCountThresholdParamName, 1);
int clicks_count = prefs::GetNoticeCardClicksCount(*profile_prefs_);
if (clicks_count >= clicks_count_threshold) {
return true;
}
return false;
}
bool NoticeCardTracker::HasNoticeCardActionsCountPrerequisites(int index) {
if (!base::FeatureList::IsEnabled(feed::kInterestFeedNoticeCardAutoDismiss))
return false;
if (!prefs::GetLastFetchHadNoticeCard(*profile_prefs_)) {
return false;
}
if (index != GetNoticeCardIndex()) {
return false;
}
return true;
}
void NoticeCardTracker::MaybeUpdateNoticeCardViewsCount(int index) {
if (!HasNoticeCardActionsCountPrerequisites(index))
return;
prefs::IncrementNoticeCardViewsCount(*profile_prefs_);
}
void NoticeCardTracker::MaybeUpdateNoticeCardClicksCount(int index) {
if (!HasNoticeCardActionsCountPrerequisites(index))
return;
prefs::IncrementNoticeCardClicksCount(*profile_prefs_);
}
} // namespace feed
\ No newline at end of file
// Copyright 2020 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_FEED_CORE_V2_NOTICE_CARD_TRACKER_H_
#define COMPONENTS_FEED_CORE_V2_NOTICE_CARD_TRACKER_H_
class PrefService;
namespace feed {
// Tracker for the notice card related actions that also provide signals based
// on those.
class NoticeCardTracker {
public:
explicit NoticeCardTracker(PrefService* profile_prefs);
NoticeCardTracker(const NoticeCardTracker&) = delete;
NoticeCardTracker& operator=(const NoticeCardTracker&) = delete;
// Capture the actions.
void OnSliceViewed(int index);
void OnOpenAction(int index);
// Get signals based on the actions.
// Indicates whether there were enough views or clicks done on the notice
// card to consider it as acknowledged by the user.
bool HasAcknowledgedNoticeCard();
private:
bool HasNoticeCardActionsCountPrerequisites(int index);
void MaybeUpdateNoticeCardViewsCount(int index);
void MaybeUpdateNoticeCardClicksCount(int index);
PrefService* profile_prefs_;
};
} // namespace feed
#endif // COMPONENTS_FEED_CORE_V2_NOTICE_CARD_TRACKER_H_
\ No newline at end of file
// Copyright 2020 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 "components/feed/core/v2/notice_card_tracker.h"
#include "base/test/scoped_feature_list.h"
#include "components/feed/core/common/pref_names.h"
#include "components/feed/core/v2/prefs.h"
#include "components/feed/feed_feature_list.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feed {
namespace {
class NoticeCardTrackerTest : public testing::Test {
public:
void SetUp() override {
feed::RegisterProfilePrefs(profile_prefs_.registry());
;
}
protected:
TestingPrefServiceSimple profile_prefs_;
};
TEST_F(NoticeCardTrackerTest,
TrackingNoticeCardActionsDoesntUpdateCountsWhenNoNoticeCard) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
feed::kInterestFeedNoticeCardAutoDismiss);
NoticeCardTracker tracker(&profile_prefs_);
prefs::SetLastFetchHadNoticeCard(profile_prefs_, false);
// Generate enough views to reach the acknowlegement threshold, but there was
// no notice card in the feed.
const int notice_card_index = 0;
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard());
}
TEST_F(NoticeCardTrackerTest,
TrackingNoticeCardActionsDoesntUpdateCountsForNonNoticeCard) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
feed::kInterestFeedNoticeCardAutoDismiss);
NoticeCardTracker tracker(&profile_prefs_);
// Generate enough views to reach the acknowlegement threshold, but the views
// were not on the notice card.
const int non_notice_card_index = 1;
tracker.OnSliceViewed(non_notice_card_index);
tracker.OnSliceViewed(non_notice_card_index);
tracker.OnSliceViewed(non_notice_card_index);
EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard());
}
TEST_F(NoticeCardTrackerTest,
AcknowledgedNoticeCardWhenEnoughViewsAndNoticeCardAt1stPos) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
feed::kInterestFeedNoticeCardAutoDismiss);
NoticeCardTracker tracker(&profile_prefs_);
const int notice_card_index = 0;
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
EXPECT_TRUE(tracker.HasAcknowledgedNoticeCard());
}
TEST_F(NoticeCardTrackerTest,
AcknowledgedNoticeCardWhenEnoughViewsAndNoticeCardAt2ndPos) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
/*enabled_features=*/{feed::kInterestFeedNoticeCardAutoDismiss,
feed::
kInterestFeedV2ClicksAndViewsConditionalUpload},
/*disabled_features=*/{});
NoticeCardTracker tracker(&profile_prefs_);
const int notice_card_index = 1;
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
EXPECT_TRUE(tracker.HasAcknowledgedNoticeCard());
}
TEST_F(NoticeCardTrackerTest,
DontAcknowledgedNoticeCardWhenNotEnoughViewsNorClicks) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(
feed::kInterestFeedNoticeCardAutoDismiss);
NoticeCardTracker tracker(&profile_prefs_);
// Generate views but not enough to reach the threshold.
const int notice_card_index = 0;
tracker.OnSliceViewed(notice_card_index);
tracker.OnSliceViewed(notice_card_index);
EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard());
}
TEST_F(NoticeCardTrackerTest, DontAcknowledgedNoticeCardWhenFeatureDisabled) {
// Generate enough views and clicks on the notice card to reach the threshold,
// but the feature is disabled.
prefs::IncrementNoticeCardClicksCount(profile_prefs_);
prefs::IncrementNoticeCardViewsCount(profile_prefs_);
prefs::IncrementNoticeCardViewsCount(profile_prefs_);
prefs::IncrementNoticeCardViewsCount(profile_prefs_);
NoticeCardTracker tracker(&profile_prefs_);
EXPECT_FALSE(tracker.HasAcknowledgedNoticeCard());
}
} // namespace
} // namespace feed
\ No newline at end of file
...@@ -106,6 +106,24 @@ bool GetHasReachedClickAndViewActionsUploadConditions( ...@@ -106,6 +106,24 @@ bool GetHasReachedClickAndViewActionsUploadConditions(
feed::prefs::kHasReachedClickAndViewActionsUploadConditions); feed::prefs::kHasReachedClickAndViewActionsUploadConditions);
} }
void IncrementNoticeCardViewsCount(PrefService& pref_service) {
int count = pref_service.GetInteger(feed::prefs::kNoticeCardViewsCount);
pref_service.SetInteger(feed::prefs::kNoticeCardViewsCount, count + 1);
}
int GetNoticeCardViewsCount(const PrefService& pref_service) {
return pref_service.GetInteger(feed::prefs::kNoticeCardViewsCount);
}
void IncrementNoticeCardClicksCount(PrefService& pref_service) {
int count = pref_service.GetInteger(feed::prefs::kNoticeCardClicksCount);
pref_service.SetInteger(feed::prefs::kNoticeCardClicksCount, count + 1);
}
int GetNoticeCardClicksCount(const PrefService& pref_service) {
return pref_service.GetInteger(feed::prefs::kNoticeCardClicksCount);
}
} // namespace prefs } // namespace prefs
} // namespace feed } // namespace feed
...@@ -52,6 +52,16 @@ void SetHasReachedClickAndViewActionsUploadConditions(PrefService& pref_service, ...@@ -52,6 +52,16 @@ void SetHasReachedClickAndViewActionsUploadConditions(PrefService& pref_service,
bool GetHasReachedClickAndViewActionsUploadConditions( bool GetHasReachedClickAndViewActionsUploadConditions(
const PrefService& pref_service); const PrefService& pref_service);
// Increment the stored notice card views count by 1.
void IncrementNoticeCardViewsCount(PrefService& pref_service);
int GetNoticeCardViewsCount(const PrefService& pref_service);
// Increment the stored notice card clicks count by 1.
void IncrementNoticeCardClicksCount(PrefService& pref_service);
int GetNoticeCardClicksCount(const PrefService& pref_service);
} // namespace prefs } // namespace prefs
} // namespace feed } // namespace feed
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "components/feed/core/proto/v2/wire/request.pb.h" #include "components/feed/core/proto/v2/wire/request.pb.h"
#include "components/feed/core/v2/config.h" #include "components/feed/core/v2/config.h"
#include "components/feed/core/v2/feed_stream.h" #include "components/feed/core/v2/feed_stream.h"
#include "components/feed/feed_feature_list.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/build_info.h" #include "base/android/build_info.h"
...@@ -136,6 +137,16 @@ feedwire::Request CreateFeedQueryRequest( ...@@ -136,6 +137,16 @@ feedwire::Request CreateFeedQueryRequest(
return request; return request;
} }
void SetNoticeCardAcknowledged(feedwire::Request* request,
const RequestMetadata& request_metadata) {
if (request_metadata.notice_card_acknowledged) {
request->mutable_feed_request()
->mutable_feed_query()
->mutable_chrome_fulfillment_info()
->set_notice_card_acknowledged(true);
}
}
} // namespace } // namespace
std::string ContentIdString(const feedwire::ContentId& content_id) { std::string ContentIdString(const feedwire::ContentId& content_id) {
...@@ -203,8 +214,10 @@ feedwire::Request CreateFeedQueryRefreshRequest( ...@@ -203,8 +214,10 @@ feedwire::Request CreateFeedQueryRefreshRequest(
feedwire::FeedQuery::RequestReason request_reason, feedwire::FeedQuery::RequestReason request_reason,
const RequestMetadata& request_metadata, const RequestMetadata& request_metadata,
const std::string& consistency_token) { const std::string& consistency_token) {
return CreateFeedQueryRequest(request_reason, request_metadata, feedwire::Request request = CreateFeedQueryRequest(
consistency_token, std::string()); request_reason, request_metadata, consistency_token, std::string());
SetNoticeCardAcknowledged(&request, request_metadata);
return request;
} }
feedwire::Request CreateFeedQueryLoadMoreRequest( feedwire::Request CreateFeedQueryLoadMoreRequest(
......
...@@ -108,5 +108,31 @@ TEST(ProtoUtilTest, DisableCapabilitiesWithFinch) { ...@@ -108,5 +108,31 @@ TEST(ProtoUtilTest, DisableCapabilitiesWithFinch) {
EXPECT_TRUE(HasCapability(request, feedwire::Capability::PREFETCH_METADATA)); EXPECT_TRUE(HasCapability(request, feedwire::Capability::PREFETCH_METADATA));
} }
TEST(ProtoUtilTest, NoticeCardAcknowledged) {
RequestMetadata request_metadata;
request_metadata.notice_card_acknowledged = true;
feedwire::Request request = CreateFeedQueryRefreshRequest(
feedwire::FeedQuery::MANUAL_REFRESH, request_metadata,
/*consistency_token=*/std::string());
EXPECT_TRUE(request.feed_request()
.feed_query()
.chrome_fulfillment_info()
.notice_card_acknowledged());
}
TEST(ProtoUtilTest, NoticeCardNotAcknowledged) {
RequestMetadata request_metadata;
request_metadata.notice_card_acknowledged = false;
feedwire::Request request = CreateFeedQueryRefreshRequest(
feedwire::FeedQuery::MANUAL_REFRESH, request_metadata,
/*consistency_token=*/std::string());
EXPECT_FALSE(request.feed_request()
.feed_query()
.chrome_fulfillment_info()
.notice_card_acknowledged());
}
} // namespace } // namespace
} // namespace feed } // namespace feed
...@@ -40,6 +40,7 @@ struct RequestMetadata { ...@@ -40,6 +40,7 @@ struct RequestMetadata {
std::string language_tag; std::string language_tag;
std::string client_instance_id; std::string client_instance_id;
DisplayMetrics display_metrics; DisplayMetrics display_metrics;
bool notice_card_acknowledged;
}; };
// Data internal to MetricsReporter which is persisted to Prefs. // Data internal to MetricsReporter which is persisted to Prefs.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment