Commit 825e89b7 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

Refactor ContextualNotificationPermissionUiSelector.

This CL introduces no behavior changes, it just moves from a model with:

  (UiToUse + QuietUiReason)

to:

  Decision = (QuietUiReason + WarningReason),

where either being base::nullopt indicates that the normal UI should be
used, or no warning should be printed, respectively.

Bug: 1087005, 1081233
Change-Id: I90563d2fc245f2f25a132566f394d74dd22c2f70
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218309
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarAndy Paicu <andypaicu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772654}
parent c997c869
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
namespace { namespace {
using UiToUse = ContextualNotificationPermissionUiSelector::UiToUse;
using QuietUiReason = ContextualNotificationPermissionUiSelector::QuietUiReason; using QuietUiReason = ContextualNotificationPermissionUiSelector::QuietUiReason;
using UiToUseWithReason = std::pair<UiToUse, base::Optional<QuietUiReason>>; using WarningReason = ContextualNotificationPermissionUiSelector::WarningReason;
using Decision = ContextualNotificationPermissionUiSelector::Decision;
// Records a histogram sample for NotificationUserExperienceQuality. // Records a histogram sample for NotificationUserExperienceQuality.
void RecordNotificationUserExperienceQuality( void RecordNotificationUserExperienceQuality(
...@@ -53,8 +53,9 @@ void RecordWarningOnlyState(bool value) { ...@@ -53,8 +53,9 @@ void RecordWarningOnlyState(bool value) {
// Attempts to decide which UI to use based on preloaded site reputation data, // Attempts to decide which UI to use based on preloaded site reputation data,
// or returns base::nullopt if not possible. |site_reputation| can be nullptr. // or returns base::nullopt if not possible. |site_reputation| can be nullptr.
base::Optional<UiToUseWithReason> GetUiToUseBasedOnSiteReputation( base::Optional<Decision> GetDecisionBasedOnSiteReputation(
const CrowdDenyPreloadData::SiteReputation* site_reputation) { const CrowdDenyPreloadData::SiteReputation* site_reputation) {
using Config = QuietNotificationPermissionUiConfig;
if (!site_reputation) { if (!site_reputation) {
RecordNotificationUserExperienceQuality( RecordNotificationUserExperienceQuality(
CrowdDenyPreloadData::SiteReputation::UNKNOWN); CrowdDenyPreloadData::SiteReputation::UNKNOWN);
...@@ -66,27 +67,29 @@ base::Optional<UiToUseWithReason> GetUiToUseBasedOnSiteReputation( ...@@ -66,27 +67,29 @@ base::Optional<UiToUseWithReason> GetUiToUseBasedOnSiteReputation(
RecordWarningOnlyState(site_reputation->warning_only()); RecordWarningOnlyState(site_reputation->warning_only());
switch (site_reputation->notification_ux_quality()) { switch (site_reputation->notification_ux_quality()) {
case CrowdDenyPreloadData::SiteReputation::ACCEPTABLE: case CrowdDenyPreloadData::SiteReputation::ACCEPTABLE: {
return std::make_pair(UiToUse::kNormalUi, base::nullopt); return Decision::UseNormalUiAndShowNoWarning();
case CrowdDenyPreloadData::SiteReputation::UNSOLICITED_PROMPTS: }
if (!QuietNotificationPermissionUiConfig::IsCrowdDenyTriggeringEnabled()) case CrowdDenyPreloadData::SiteReputation::UNSOLICITED_PROMPTS: {
return base::nullopt;
if (site_reputation->warning_only()) if (site_reputation->warning_only())
return std::make_pair(UiToUse::kNormalUi, base::nullopt); return Decision::UseNormalUiAndShowNoWarning();
return std::make_pair(UiToUse::kQuietUi, if (!Config::IsCrowdDenyTriggeringEnabled())
QuietUiReason::kTriggeredByCrowdDeny);
case CrowdDenyPreloadData::SiteReputation::ABUSIVE_PROMPTS:
if (!QuietNotificationPermissionUiConfig::
IsAbusiveRequestBlockingEnabled()) {
return base::nullopt; return base::nullopt;
return Decision(QuietUiReason::kTriggeredByCrowdDeny,
Decision::ShowNoWarning());
} }
case CrowdDenyPreloadData::SiteReputation::ABUSIVE_PROMPTS: {
if (site_reputation->warning_only()) if (site_reputation->warning_only())
return std::make_pair(UiToUse::kNormalUi, base::nullopt); return Decision::UseNormalUiAndShowNoWarning();
return std::make_pair(UiToUse::kQuietUi, if (!Config::IsAbusiveRequestBlockingEnabled())
QuietUiReason::kTriggeredDueToAbusiveRequests); return base::nullopt;
case CrowdDenyPreloadData::SiteReputation::UNKNOWN: return Decision(QuietUiReason::kTriggeredDueToAbusiveRequests,
Decision::ShowNoWarning());
}
case CrowdDenyPreloadData::SiteReputation::UNKNOWN: {
return base::nullopt; return base::nullopt;
} }
}
NOTREACHED(); NOTREACHED();
return base::nullopt; return base::nullopt;
...@@ -125,7 +128,7 @@ void ContextualNotificationPermissionUiSelector::SelectUiToUse( ...@@ -125,7 +128,7 @@ void ContextualNotificationPermissionUiSelector::SelectUiToUse(
DCHECK(callback_); DCHECK(callback_);
if (!base::FeatureList::IsEnabled(features::kQuietNotificationPrompts)) { if (!base::FeatureList::IsEnabled(features::kQuietNotificationPrompts)) {
Notify(UiToUse::kNormalUi, base::nullopt); Notify(Decision::UseNormalUiAndShowNoWarning());
return; return;
} }
...@@ -146,15 +149,16 @@ ContextualNotificationPermissionUiSelector:: ...@@ -146,15 +149,16 @@ ContextualNotificationPermissionUiSelector::
void ContextualNotificationPermissionUiSelector::EvaluatePerSiteTriggers( void ContextualNotificationPermissionUiSelector::EvaluatePerSiteTriggers(
const url::Origin& origin) { const url::Origin& origin) {
auto ui_to_use_with_reason = GetUiToUseBasedOnSiteReputation( base::Optional<Decision> decision = GetDecisionBasedOnSiteReputation(
CrowdDenyPreloadData::GetInstance()->GetReputationDataForSite(origin)); CrowdDenyPreloadData::GetInstance()->GetReputationDataForSite(origin));
if (!ui_to_use_with_reason ||
ui_to_use_with_reason->first == UiToUse::kNormalUi) { // If the PreloadData suggests this is an unacceptable site, ping Safe
OnPerSiteTriggersEvaluated(UiToUse::kNormalUi, base::nullopt); // Browsing to verify; but do not ping if it is not warranted.
if (!decision || (!decision->quiet_ui_reason && !decision->warning_reason)) {
OnPerSiteTriggersEvaluated(Decision::UseNormalUiAndShowNoWarning());
return; return;
} }
// PreloadData suggests an unacceptable site, ping Safe Browsing to verify.
DCHECK(!safe_browsing_request_); DCHECK(!safe_browsing_request_);
DCHECK(g_browser_process->safe_browsing_service()); DCHECK(g_browser_process->safe_browsing_service());
...@@ -165,11 +169,11 @@ void ContextualNotificationPermissionUiSelector::EvaluatePerSiteTriggers( ...@@ -165,11 +169,11 @@ void ContextualNotificationPermissionUiSelector::EvaluatePerSiteTriggers(
base::DefaultClock::GetInstance(), origin, base::DefaultClock::GetInstance(), origin,
base::BindOnce(&ContextualNotificationPermissionUiSelector:: base::BindOnce(&ContextualNotificationPermissionUiSelector::
OnSafeBrowsingVerdictReceived, OnSafeBrowsingVerdictReceived,
base::Unretained(this), *ui_to_use_with_reason->second)); base::Unretained(this), *decision));
} }
void ContextualNotificationPermissionUiSelector::OnSafeBrowsingVerdictReceived( void ContextualNotificationPermissionUiSelector::OnSafeBrowsingVerdictReceived(
QuietUiReason candidate_quiet_ui_reason, Decision candidate_decision,
CrowdDenySafeBrowsingRequest::Verdict verdict) { CrowdDenySafeBrowsingRequest::Verdict verdict) {
DCHECK(safe_browsing_request_); DCHECK(safe_browsing_request_);
DCHECK(callback_); DCHECK(callback_);
...@@ -178,39 +182,34 @@ void ContextualNotificationPermissionUiSelector::OnSafeBrowsingVerdictReceived( ...@@ -178,39 +182,34 @@ void ContextualNotificationPermissionUiSelector::OnSafeBrowsingVerdictReceived(
switch (verdict) { switch (verdict) {
case CrowdDenySafeBrowsingRequest::Verdict::kAcceptable: case CrowdDenySafeBrowsingRequest::Verdict::kAcceptable:
OnPerSiteTriggersEvaluated(UiToUse::kNormalUi, base::nullopt); OnPerSiteTriggersEvaluated(Decision::UseNormalUiAndShowNoWarning());
break; break;
case CrowdDenySafeBrowsingRequest::Verdict::kUnacceptable: case CrowdDenySafeBrowsingRequest::Verdict::kUnacceptable:
OnPerSiteTriggersEvaluated(UiToUse::kQuietUi, candidate_quiet_ui_reason); if (candidate_decision.quiet_ui_reason &&
ShouldHoldBackQuietUI(*(candidate_decision.quiet_ui_reason))) {
candidate_decision.quiet_ui_reason.reset();
}
OnPerSiteTriggersEvaluated(candidate_decision);
break; break;
} }
} }
void ContextualNotificationPermissionUiSelector::OnPerSiteTriggersEvaluated( void ContextualNotificationPermissionUiSelector::OnPerSiteTriggersEvaluated(
UiToUse ui_to_use, Decision decision) {
base::Optional<QuietUiReason> quiet_ui_reason) {
if (ui_to_use == UiToUse::kQuietUi &&
!ShouldHoldBackQuietUI(*quiet_ui_reason)) {
Notify(UiToUse::kQuietUi, quiet_ui_reason);
return;
}
// Still show the quiet UI if it is enabled for all sites, even if per-site // Still show the quiet UI if it is enabled for all sites, even if per-site
// conditions did not trigger showing the quiet UI on this origin. // conditions did not trigger showing the quiet UI on this origin.
if (profile_->GetPrefs()->GetBoolean( if (!decision.quiet_ui_reason &&
profile_->GetPrefs()->GetBoolean(
prefs::kEnableQuietNotificationPermissionUi)) { prefs::kEnableQuietNotificationPermissionUi)) {
Notify(UiToUse::kQuietUi, QuietUiReason::kEnabledInPrefs); decision.quiet_ui_reason = QuietUiReason::kEnabledInPrefs;
return;
} }
Notify(UiToUse::kNormalUi, base::nullopt); Notify(decision);
} }
void ContextualNotificationPermissionUiSelector::Notify( void ContextualNotificationPermissionUiSelector::Notify(
UiToUse ui_to_use, const Decision& decision) {
base::Optional<QuietUiReason> quiet_ui_reason) { std::move(callback_).Run(decision);
DCHECK_EQ(ui_to_use == UiToUse::kQuietUi, !!quiet_ui_reason);
std::move(callback_).Run(ui_to_use, quiet_ui_reason);
} }
// static // static
...@@ -52,13 +52,10 @@ class ContextualNotificationPermissionUiSelector ...@@ -52,13 +52,10 @@ class ContextualNotificationPermissionUiSelector
void EvaluatePerSiteTriggers(const url::Origin& origin); void EvaluatePerSiteTriggers(const url::Origin& origin);
void OnSafeBrowsingVerdictReceived( void OnSafeBrowsingVerdictReceived(
QuietUiReason candidate_quiet_ui_reason, Decision candidate_decision,
CrowdDenySafeBrowsingRequest::Verdict verdict); CrowdDenySafeBrowsingRequest::Verdict verdict);
void OnPerSiteTriggersEvaluated( void OnPerSiteTriggersEvaluated(Decision decision);
UiToUse ui_to_use, void Notify(const Decision& decision);
base::Optional<QuietUiReason> quiet_ui_reason);
void Notify(UiToUse ui_to_use, base::Optional<QuietUiReason> quiet_ui_reason);
Profile* profile_; Profile* profile_;
......
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
namespace { namespace {
using QuietUiReason = ContextualNotificationPermissionUiSelector::QuietUiReason;
using WarningReason = ContextualNotificationPermissionUiSelector::WarningReason;
using Decision = ContextualNotificationPermissionUiSelector::Decision;
using SiteReputation = chrome_browser_crowd_deny::SiteReputation;
constexpr char kTestDomainUnknown[] = "unknown.com"; constexpr char kTestDomainUnknown[] = "unknown.com";
constexpr char kTestDomainAcceptable[] = "acceptable.com"; constexpr char kTestDomainAcceptable[] = "acceptable.com";
constexpr char kTestDomainSpammy[] = "spammy.com"; constexpr char kTestDomainSpammy[] = "spammy.com";
...@@ -66,11 +71,6 @@ constexpr const char* kAllTestingOrigins[] = { ...@@ -66,11 +71,6 @@ constexpr const char* kAllTestingOrigins[] = {
class ContextualNotificationPermissionUiSelectorTest : public testing::Test { class ContextualNotificationPermissionUiSelectorTest : public testing::Test {
public: public:
using UiToUse = ContextualNotificationPermissionUiSelector::UiToUse;
using QuietUiReason =
ContextualNotificationPermissionUiSelector::QuietUiReason;
using SiteReputation = chrome_browser_crowd_deny::SiteReputation;
ContextualNotificationPermissionUiSelectorTest() ContextualNotificationPermissionUiSelectorTest()
: testing_profile_(std::make_unique<TestingProfile>()), : testing_profile_(std::make_unique<TestingProfile>()),
contextual_selector_(testing_profile_.get()) {} contextual_selector_(testing_profile_.get()) {}
...@@ -175,17 +175,22 @@ class ContextualNotificationPermissionUiSelectorTest : public testing::Test { ...@@ -175,17 +175,22 @@ class ContextualNotificationPermissionUiSelectorTest : public testing::Test {
void QueryAndExpectDecisionForUrl( void QueryAndExpectDecisionForUrl(
const GURL& origin, const GURL& origin,
UiToUse ui_to_use, base::Optional<QuietUiReason> quiet_ui_reason,
base::Optional<QuietUiReason> quiet_ui_reason) { base::Optional<WarningReason> warning_reason) {
permissions::MockPermissionRequest mock_request( permissions::MockPermissionRequest mock_request(
std::string(), std::string(),
permissions::PermissionRequestType::PERMISSION_NOTIFICATIONS, origin); permissions::PermissionRequestType::PERMISSION_NOTIFICATIONS, origin);
base::MockCallback< base::MockCallback<
ContextualNotificationPermissionUiSelector::DecisionMadeCallback> ContextualNotificationPermissionUiSelector::DecisionMadeCallback>
mock_callback; mock_callback;
EXPECT_CALL(mock_callback, Run(ui_to_use, quiet_ui_reason)); Decision actual_decison(base::nullopt, base::nullopt);
EXPECT_CALL(mock_callback, Run)
.WillRepeatedly(testing::SaveArg<0>(&actual_decison));
contextual_selector_.SelectUiToUse(&mock_request, mock_callback.Get()); contextual_selector_.SelectUiToUse(&mock_request, mock_callback.Get());
task_environment_.RunUntilIdle(); task_environment_.RunUntilIdle();
testing::Mock::VerifyAndClearExpectations(&mock_callback);
EXPECT_EQ(quiet_ui_reason, actual_decison.quiet_ui_reason);
EXPECT_EQ(warning_reason, actual_decison.warning_reason);
} }
private: private:
...@@ -225,8 +230,8 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -225,8 +230,8 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts negative"); SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts negative");
for (const auto* origin_string : kAllTestingOrigins) { for (const auto* origin_string : kAllTestingOrigins) {
SCOPED_TRACE(origin_string); SCOPED_TRACE(origin_string);
QueryAndExpectDecisionForUrl(GURL(origin_string), UiToUse::kNormalUi, QueryAndExpectDecisionForUrl(GURL(origin_string), Decision::UseNormalUi(),
base::nullopt); Decision::ShowNoWarning());
} }
} }
...@@ -237,8 +242,9 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -237,8 +242,9 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts negative"); SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts negative");
for (const auto* origin_string : kAllTestingOrigins) { for (const auto* origin_string : kAllTestingOrigins) {
SCOPED_TRACE(origin_string); SCOPED_TRACE(origin_string);
QueryAndExpectDecisionForUrl(GURL(origin_string), UiToUse::kQuietUi, QueryAndExpectDecisionForUrl(GURL(origin_string),
QuietUiReason::kEnabledInPrefs); QuietUiReason::kEnabledInPrefs,
Decision::ShowNoWarning());
} }
} }
...@@ -248,27 +254,29 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -248,27 +254,29 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
const struct { const struct {
const char* origin_string; const char* origin_string;
UiToUse expected_ui; base::Optional<QuietUiReason> expected_ui_reason =
base::Optional<QuietUiReason> expected_ui_reason; Decision::UseNormalUi();
base::Optional<WarningReason> expected_warning_reason =
Decision::ShowNoWarning();
} kTestCases[] = { } kTestCases[] = {
{kTestOriginNoData, UiToUse::kNormalUi, base::nullopt}, {kTestOriginNoData},
{kTestOriginUnknown, UiToUse::kNormalUi, base::nullopt}, {kTestOriginUnknown},
{kTestOriginAcceptable, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAcceptable},
{kTestOriginSpammy, UiToUse::kQuietUi, {kTestOriginSpammy, QuietUiReason::kTriggeredByCrowdDeny},
QuietUiReason::kTriggeredByCrowdDeny}, {kTestOriginSpammyWarn},
{kTestOriginSpammyWarn, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAbusivePrompts,
{kTestOriginAbusivePrompts, UiToUse::kQuietUi,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginSubDomainOfAbusivePrompts, UiToUse::kQuietUi, {kTestOriginSubDomainOfAbusivePrompts,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginAbusivePromptsWarn, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAbusivePromptsWarn},
}; };
SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts positive"); SCOPED_TRACE("Quiet UI disabled in prefs, Safe Browsing verdicts positive");
for (const auto& test : kTestCases) { for (const auto& test : kTestCases) {
SCOPED_TRACE(test.origin_string); SCOPED_TRACE(test.origin_string);
QueryAndExpectDecisionForUrl(GURL(test.origin_string), test.expected_ui, QueryAndExpectDecisionForUrl(GURL(test.origin_string),
test.expected_ui_reason); test.expected_ui_reason,
test.expected_warning_reason);
} }
} }
...@@ -278,30 +286,29 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -278,30 +286,29 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
const struct { const struct {
const char* origin_string; const char* origin_string;
UiToUse expected_ui; base::Optional<QuietUiReason> expected_ui_reason =
base::Optional<QuietUiReason> expected_ui_reason; Decision::UseNormalUi();
base::Optional<WarningReason> expected_warning_reason =
Decision::ShowNoWarning();
} kTestCases[] = { } kTestCases[] = {
{kTestOriginNoData, UiToUse::kQuietUi, QuietUiReason::kEnabledInPrefs}, {kTestOriginNoData, QuietUiReason::kEnabledInPrefs},
{kTestOriginUnknown, UiToUse::kQuietUi, QuietUiReason::kEnabledInPrefs}, {kTestOriginUnknown, QuietUiReason::kEnabledInPrefs},
{kTestOriginAcceptable, UiToUse::kQuietUi, {kTestOriginAcceptable, QuietUiReason::kEnabledInPrefs},
QuietUiReason::kEnabledInPrefs}, {kTestOriginSpammy, QuietUiReason::kTriggeredByCrowdDeny},
{kTestOriginSpammy, UiToUse::kQuietUi, {kTestOriginSpammyWarn, QuietUiReason::kEnabledInPrefs},
QuietUiReason::kTriggeredByCrowdDeny}, {kTestOriginAbusivePrompts,
{kTestOriginSpammyWarn, UiToUse::kQuietUi,
QuietUiReason::kEnabledInPrefs},
{kTestOriginAbusivePrompts, UiToUse::kQuietUi,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginSubDomainOfAbusivePrompts, UiToUse::kQuietUi, {kTestOriginSubDomainOfAbusivePrompts,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginAbusivePromptsWarn, UiToUse::kQuietUi, {kTestOriginAbusivePromptsWarn, QuietUiReason::kEnabledInPrefs},
QuietUiReason::kEnabledInPrefs},
}; };
SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts positive"); SCOPED_TRACE("Quiet UI enabled in prefs, Safe Browsing verdicts positive");
for (const auto& test : kTestCases) { for (const auto& test : kTestCases) {
SCOPED_TRACE(test.origin_string); SCOPED_TRACE(test.origin_string);
QueryAndExpectDecisionForUrl(GURL(test.origin_string), test.expected_ui, QueryAndExpectDecisionForUrl(GURL(test.origin_string),
test.expected_ui_reason); test.expected_ui_reason,
test.expected_warning_reason);
} }
} }
} }
...@@ -316,8 +323,8 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, FeatureDisabled) { ...@@ -316,8 +323,8 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, FeatureDisabled) {
for (const auto* origin_string : kAllTestingOrigins) { for (const auto* origin_string : kAllTestingOrigins) {
SCOPED_TRACE(origin_string); SCOPED_TRACE(origin_string);
QueryAndExpectDecisionForUrl(GURL(origin_string), UiToUse::kNormalUi, QueryAndExpectDecisionForUrl(GURL(origin_string), Decision::UseNormalUi(),
base::nullopt); Decision::ShowNoWarning());
} }
} }
...@@ -335,8 +342,9 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, AllTriggersDisabled) { ...@@ -335,8 +342,9 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, AllTriggersDisabled) {
for (const auto* origin_string : kAllTestingOrigins) { for (const auto* origin_string : kAllTestingOrigins) {
SCOPED_TRACE(origin_string); SCOPED_TRACE(origin_string);
QueryAndExpectDecisionForUrl(GURL(origin_string), UiToUse::kQuietUi, QueryAndExpectDecisionForUrl(GURL(origin_string),
QuietUiReason::kEnabledInPrefs); QuietUiReason::kEnabledInPrefs,
Decision::ShowNoWarning());
} }
} }
...@@ -355,21 +363,22 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, OnlyCrowdDenyEnabled) { ...@@ -355,21 +363,22 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, OnlyCrowdDenyEnabled) {
const struct { const struct {
const char* origin_string; const char* origin_string;
UiToUse expected_ui; base::Optional<QuietUiReason> expected_ui_reason = Decision::UseNormalUi();
base::Optional<QuietUiReason> expected_ui_reason; base::Optional<WarningReason> expected_warning_reason =
Decision::ShowNoWarning();
} kTestCases[] = { } kTestCases[] = {
{kTestOriginSpammy, UiToUse::kQuietUi, {kTestOriginSpammy, QuietUiReason::kTriggeredByCrowdDeny},
QuietUiReason::kTriggeredByCrowdDeny}, {kTestOriginSpammyWarn},
{kTestOriginSpammyWarn, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAbusivePrompts},
{kTestOriginAbusivePrompts, UiToUse::kNormalUi, base::nullopt}, {kTestOriginSubDomainOfAbusivePrompts},
{kTestOriginSubDomainOfAbusivePrompts, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAbusivePromptsWarn},
{kTestOriginAbusivePromptsWarn, UiToUse::kNormalUi, base::nullopt},
}; };
for (const auto& test : kTestCases) { for (const auto& test : kTestCases) {
SCOPED_TRACE(test.origin_string); SCOPED_TRACE(test.origin_string);
QueryAndExpectDecisionForUrl(GURL(test.origin_string), test.expected_ui, QueryAndExpectDecisionForUrl(GURL(test.origin_string),
test.expected_ui_reason); test.expected_ui_reason,
test.expected_warning_reason);
} }
} }
...@@ -389,22 +398,24 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -389,22 +398,24 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
const struct { const struct {
const char* origin_string; const char* origin_string;
UiToUse expected_ui; base::Optional<QuietUiReason> expected_ui_reason = Decision::UseNormalUi();
base::Optional<QuietUiReason> expected_ui_reason; base::Optional<WarningReason> expected_warning_reason =
Decision::ShowNoWarning();
} kTestCases[] = { } kTestCases[] = {
{kTestOriginSpammy, UiToUse::kNormalUi, base::nullopt}, {kTestOriginSpammy},
{kTestOriginSpammyWarn, UiToUse::kNormalUi, base::nullopt}, {kTestOriginSpammyWarn},
{kTestOriginAbusivePrompts, UiToUse::kQuietUi, {kTestOriginAbusivePrompts,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginSubDomainOfAbusivePrompts, UiToUse::kQuietUi, {kTestOriginSubDomainOfAbusivePrompts,
QuietUiReason::kTriggeredDueToAbusiveRequests}, QuietUiReason::kTriggeredDueToAbusiveRequests},
{kTestOriginAbusivePromptsWarn, UiToUse::kNormalUi, base::nullopt}, {kTestOriginAbusivePromptsWarn},
}; };
for (const auto& test : kTestCases) { for (const auto& test : kTestCases) {
SCOPED_TRACE(test.origin_string); SCOPED_TRACE(test.origin_string);
QueryAndExpectDecisionForUrl(GURL(test.origin_string), test.expected_ui, QueryAndExpectDecisionForUrl(GURL(test.origin_string),
test.expected_ui_reason); test.expected_ui_reason,
test.expected_warning_reason);
} }
} }
...@@ -413,17 +424,16 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -413,17 +424,16 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
const struct { const struct {
std::string holdback_chance; std::string holdback_chance;
bool enabled_in_prefs; bool enabled_in_prefs;
UiToUse expected_ui;
base::Optional<QuietUiReason> expected_ui_reason; base::Optional<QuietUiReason> expected_ui_reason;
bool expected_histogram_bucket; bool expected_histogram_bucket;
} kTestCases[] = { } kTestCases[] = {
// 100% chance to holdback, the UI used should be the normal UI. // 100% chance to holdback, the UI used should be the normal UI.
{"1.0", false, UiToUse::kNormalUi, base::nullopt, true}, {"1.0", false, Decision::UseNormalUi(), true},
// 0% chance to holdback, the UI used should be the quiet UI. // 0% chance to holdback, the UI used should be the quiet UI.
{"0.0", false, UiToUse::kQuietUi, QuietUiReason::kTriggeredByCrowdDeny}, {"0.0", false, QuietUiReason::kTriggeredByCrowdDeny},
// 100% chance to holdback but the quiet UI is enabled by the user in // 100% chance to holdback but the quiet UI is enabled by the user in
// prefs, the UI used should be the quiet UI. // prefs, the UI used should be the quiet UI.
{"1.0", true, UiToUse::kQuietUi, QuietUiReason::kEnabledInPrefs, true}, {"1.0", true, QuietUiReason::kEnabledInPrefs, true},
}; };
LoadTestPreloadData(); LoadTestPreloadData();
...@@ -439,19 +449,26 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest, ...@@ -439,19 +449,26 @@ TEST_F(ContextualNotificationPermissionUiSelectorTest,
features::kQuietNotificationPrompts, features::kQuietNotificationPrompts,
{{Config::kEnableAdaptiveActivation, "true"}, {{Config::kEnableAdaptiveActivation, "true"},
{Config::kEnableAbusiveRequestBlocking, "true"}, {Config::kEnableAbusiveRequestBlocking, "true"},
{Config::kEnableAbusiveRequestWarning, "true"},
{Config::kEnableCrowdDenyTriggering, "true"}, {Config::kEnableCrowdDenyTriggering, "true"},
{Config::kCrowdDenyHoldBackChance, test.holdback_chance}}); {Config::kCrowdDenyHoldBackChance, test.holdback_chance}});
SetQuietUiEnabledInPrefs(test.enabled_in_prefs); SetQuietUiEnabledInPrefs(test.enabled_in_prefs);
base::HistogramTester histograms; base::HistogramTester histograms;
QueryAndExpectDecisionForUrl(GURL(kTestOriginSpammy), test.expected_ui, QueryAndExpectDecisionForUrl(GURL(kTestOriginSpammy),
test.expected_ui_reason); test.expected_ui_reason,
Decision::ShowNoWarning());
// The hold-back should not apply to other per-site triggers. // The hold-back should not apply to other per-site triggers.
QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusivePrompts), QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusivePrompts),
UiToUse::kQuietUi, QuietUiReason::kTriggeredDueToAbusiveRequests,
QuietUiReason::kTriggeredDueToAbusiveRequests); Decision::ShowNoWarning());
QueryAndExpectDecisionForUrl(GURL(kTestOriginAbusivePromptsWarn),
test.enabled_in_prefs
? QuietUiReason::kEnabledInPrefs
: Decision::UseNormalUi(),
Decision::ShowNoWarning());
auto expected_bucket = static_cast<base::HistogramBase::Sample>( auto expected_bucket = static_cast<base::HistogramBase::Sample>(
test.expected_histogram_bucket); test.expected_histogram_bucket);
......
...@@ -56,7 +56,8 @@ class TestQuietNotificationPermissionUiSelector ...@@ -56,7 +56,8 @@ class TestQuietNotificationPermissionUiSelector
// permissions::NotificationPermissionUiSelector: // permissions::NotificationPermissionUiSelector:
void SelectUiToUse(permissions::PermissionRequest* request, void SelectUiToUse(permissions::PermissionRequest* request,
DecisionMadeCallback callback) override { DecisionMadeCallback callback) override {
std::move(callback).Run(UiToUse::kQuietUi, simulated_reason_for_quiet_ui_); std::move(callback).Run(
Decision(simulated_reason_for_quiet_ui_, base::nullopt));
} }
private: private:
......
...@@ -12,6 +12,7 @@ source_set("permissions") { ...@@ -12,6 +12,7 @@ source_set("permissions") {
"contexts/window_placement_permission_context.h", "contexts/window_placement_permission_context.h",
"features.cc", "features.cc",
"features.h", "features.h",
"notification_permission_ui_selector.cc",
"notification_permission_ui_selector.h", "notification_permission_ui_selector.h",
"permission_context_base.cc", "permission_context_base.cc",
"permission_context_base.h", "permission_context_base.h",
......
// 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/permissions/notification_permission_ui_selector.h"
namespace permissions {
NotificationPermissionUiSelector::Decision::Decision(
base::Optional<QuietUiReason> quiet_ui_reason,
base::Optional<WarningReason> warning_reason)
: quiet_ui_reason(quiet_ui_reason), warning_reason(warning_reason) {}
NotificationPermissionUiSelector::Decision::~Decision() = default;
NotificationPermissionUiSelector::Decision::Decision(const Decision&) = default;
NotificationPermissionUiSelector::Decision&
NotificationPermissionUiSelector::Decision::operator=(const Decision&) =
default;
// static
NotificationPermissionUiSelector::Decision
NotificationPermissionUiSelector::Decision::UseNormalUiAndShowNoWarning() {
return Decision(UseNormalUi(), ShowNoWarning());
}
} // namespace permissions
...@@ -5,30 +5,58 @@ ...@@ -5,30 +5,58 @@
#ifndef COMPONENTS_PERMISSIONS_NOTIFICATION_PERMISSION_UI_SELECTOR_H_ #ifndef COMPONENTS_PERMISSIONS_NOTIFICATION_PERMISSION_UI_SELECTOR_H_
#define COMPONENTS_PERMISSIONS_NOTIFICATION_PERMISSION_UI_SELECTOR_H_ #define COMPONENTS_PERMISSIONS_NOTIFICATION_PERMISSION_UI_SELECTOR_H_
#include "base/callback_forward.h"
#include "base/optional.h"
#include "components/permissions/permission_request.h" #include "components/permissions/permission_request.h"
namespace permissions { namespace permissions {
// The interface for implementations that decide if the quiet prompt UI should // The interface for implementations that decide if the quiet prompt UI should
// be used to display a notification permission |request|. // be used to display a notification permission |request|, whether a warning
// should be printed to the Dev Tools console, and the reasons for both.
// //
// Implementations of interface are expected to have long-lived instances that // Implementations of interface are expected to have long-lived instances that
// can support multiple requests, but only one at a time. // can support multiple requests, but only one at a time.
class NotificationPermissionUiSelector { class NotificationPermissionUiSelector {
public: public:
enum class UiToUse {
kNormalUi,
kQuietUi,
};
enum class QuietUiReason { enum class QuietUiReason {
kEnabledInPrefs, kEnabledInPrefs,
kTriggeredByCrowdDeny, kTriggeredByCrowdDeny,
kTriggeredDueToAbusiveRequests, kTriggeredDueToAbusiveRequests,
}; };
using DecisionMadeCallback = enum class WarningReason {
base::OnceCallback<void(UiToUse, base::Optional<QuietUiReason>)>; kAbusiveRequests,
};
struct Decision {
Decision(base::Optional<QuietUiReason> quiet_ui_reason,
base::Optional<WarningReason> warning_reason);
~Decision();
Decision(const Decision&);
Decision& operator=(const Decision&);
static constexpr base::Optional<QuietUiReason> UseNormalUi() {
return base::nullopt;
}
static constexpr base::Optional<WarningReason> ShowNoWarning() {
return base::nullopt;
}
static Decision UseNormalUiAndShowNoWarning();
// The reason for showing the quiet UI, or `base::nullopt` if the normal UI
// should be used.
base::Optional<QuietUiReason> quiet_ui_reason;
// The reason for printing a warning to the console, or `base::nullopt` if
// no warning should be printed.
base::Optional<WarningReason> warning_reason;
};
using DecisionMadeCallback = base::OnceCallback<void(const Decision&)>;
virtual ~NotificationPermissionUiSelector() {} virtual ~NotificationPermissionUiSelector() {}
......
...@@ -371,7 +371,8 @@ void PermissionRequestManager::DequeueRequestIfNeeded() { ...@@ -371,7 +371,8 @@ void PermissionRequestManager::DequeueRequestIfNeeded() {
&PermissionRequestManager::OnSelectedUiToUseForNotifications, &PermissionRequestManager::OnSelectedUiToUseForNotifications,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
} else { } else {
current_request_ui_to_use_ = UiToUse::kNormalUi; current_request_ui_to_use_ =
UiDecision(UiDecision::UseNormalUi(), UiDecision::ShowNoWarning());
ScheduleShowBubble(); ScheduleShowBubble();
} }
} }
...@@ -479,7 +480,6 @@ void PermissionRequestManager::FinalizeBubble( ...@@ -479,7 +480,6 @@ void PermissionRequestManager::FinalizeBubble(
current_request_view_shown_to_user_ = false; current_request_view_shown_to_user_ = false;
current_request_ui_to_use_.reset(); current_request_ui_to_use_.reset();
current_request_quiet_ui_reason_.reset();
if (view_) if (view_)
DeleteBubble(); DeleteBubble();
...@@ -579,12 +579,12 @@ bool PermissionRequestManager::ShouldCurrentRequestUseQuietUI() const { ...@@ -579,12 +579,12 @@ bool PermissionRequestManager::ShouldCurrentRequestUseQuietUI() const {
// ContentSettingImageModel might call into this method if the user switches // ContentSettingImageModel might call into this method if the user switches
// between tabs while the |notification_permission_ui_selector_| is pending. // between tabs while the |notification_permission_ui_selector_| is pending.
return current_request_ui_to_use_ && return current_request_ui_to_use_ &&
*current_request_ui_to_use_ == UiToUse::kQuietUi; current_request_ui_to_use_->quiet_ui_reason;
} }
PermissionRequestManager::QuietUiReason PermissionRequestManager::QuietUiReason
PermissionRequestManager::ReasonForUsingQuietUi() const { PermissionRequestManager::ReasonForUsingQuietUi() const {
return *current_request_quiet_ui_reason_; return *(current_request_ui_to_use_->quiet_ui_reason);
} }
bool PermissionRequestManager::IsRequestInProgress() const { bool PermissionRequestManager::IsRequestInProgress() const {
...@@ -602,10 +602,8 @@ void PermissionRequestManager::NotifyBubbleRemoved() { ...@@ -602,10 +602,8 @@ void PermissionRequestManager::NotifyBubbleRemoved() {
} }
void PermissionRequestManager::OnSelectedUiToUseForNotifications( void PermissionRequestManager::OnSelectedUiToUseForNotifications(
UiToUse ui_to_use, const UiDecision& decision) {
base::Optional<QuietUiReason> quiet_ui_reason) { current_request_ui_to_use_ = decision;
current_request_ui_to_use_ = ui_to_use;
current_request_quiet_ui_reason_ = quiet_ui_reason;
ScheduleShowBubble(); ScheduleShowBubble();
} }
......
...@@ -54,8 +54,9 @@ class PermissionRequestManager ...@@ -54,8 +54,9 @@ class PermissionRequestManager
enum AutoResponseType { NONE, ACCEPT_ALL, DENY_ALL, DISMISS }; enum AutoResponseType { NONE, ACCEPT_ALL, DENY_ALL, DISMISS };
using UiToUse = NotificationPermissionUiSelector::UiToUse; using UiDecision = NotificationPermissionUiSelector::Decision;
using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason; using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason;
using WarningReason = NotificationPermissionUiSelector::WarningReason;
~PermissionRequestManager() override; ~PermissionRequestManager() override;
...@@ -80,6 +81,7 @@ class PermissionRequestManager ...@@ -80,6 +81,7 @@ class PermissionRequestManager
// directly by the user in notifications settings, or via automatic logic that // directly by the user in notifications settings, or via automatic logic that
// might trigger the current request to use the quiet UI. // might trigger the current request to use the quiet UI.
bool ShouldCurrentRequestUseQuietUI() const; bool ShouldCurrentRequestUseQuietUI() const;
// If |ShouldCurrentRequestUseQuietUI| return true, this will provide a reason // If |ShouldCurrentRequestUseQuietUI| return true, this will provide a reason
// as to why the quiet UI needs to be used. // as to why the quiet UI needs to be used.
QuietUiReason ReasonForUsingQuietUi() const; QuietUiReason ReasonForUsingQuietUi() const;
...@@ -180,9 +182,7 @@ class PermissionRequestManager ...@@ -180,9 +182,7 @@ class PermissionRequestManager
void NotifyBubbleAdded(); void NotifyBubbleAdded();
void NotifyBubbleRemoved(); void NotifyBubbleRemoved();
void OnSelectedUiToUseForNotifications( void OnSelectedUiToUseForNotifications(const UiDecision& decision);
UiToUse ui_to_use,
base::Optional<QuietUiReason> quiet_ui_reason);
PermissionPromptDisposition DetermineCurrentRequestUIDispositionForUMA(); PermissionPromptDisposition DetermineCurrentRequestUIDispositionForUMA();
...@@ -226,14 +226,9 @@ class PermissionRequestManager ...@@ -226,14 +226,9 @@ class PermissionRequestManager
bool current_request_view_shown_to_user_ = false; bool current_request_view_shown_to_user_ = false;
// Whether to use the normal or quiet UI to display the current permission // Whether to use the normal or quiet UI to display the current permission
// |requests_|, or nullopt if we are still waiting on the result from the // |requests_|, and whether to show warnings. This will be nullopt if we are
// |notification_permission_ui_selector_|. // still waiting on the result from |notification_permission_ui_selector_|.
base::Optional<UiToUse> current_request_ui_to_use_; base::Optional<UiDecision> current_request_ui_to_use_;
// The reason for using the quiet UI to display the current permission
// |requests_|, or nullopt if we are still waiting for the response from the
// |notification_permission_ui_selector_| or we are using the normal UI.
base::Optional<QuietUiReason> current_request_quiet_ui_reason_;
// Whether the bubble is being destroyed by this class, rather than in // Whether the bubble is being destroyed by this class, rather than in
// response to a UI event. In this case, callbacks from the bubble itself // response to a UI event. In this case, callbacks from the bubble itself
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
namespace permissions { namespace permissions {
namespace {
using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason;
}
class PermissionRequestManagerTest : public content::RenderViewHostTestHarness { class PermissionRequestManagerTest : public content::RenderViewHostTestHarness {
public: public:
PermissionRequestManagerTest() PermissionRequestManagerTest()
...@@ -541,34 +545,34 @@ TEST_F(PermissionRequestManagerTest, UMAForTabSwitching) { ...@@ -541,34 +545,34 @@ TEST_F(PermissionRequestManagerTest, UMAForTabSwitching) {
class MockNotificationPermissionUiSelector class MockNotificationPermissionUiSelector
: public NotificationPermissionUiSelector { : public NotificationPermissionUiSelector {
public: public:
explicit MockNotificationPermissionUiSelector(UiToUse ui_to_use, bool async) { explicit MockNotificationPermissionUiSelector(
ui_to_use_ = ui_to_use; base::Optional<QuietUiReason> quiet_ui_reason,
bool async) {
quiet_ui_reason_ = quiet_ui_reason;
async_ = async; async_ = async;
} }
void SelectUiToUse(PermissionRequest* request, void SelectUiToUse(PermissionRequest* request,
DecisionMadeCallback callback) override { DecisionMadeCallback callback) override {
base::Optional<QuietUiReason> reason; Decision decision(quiet_ui_reason_, Decision::ShowNoWarning());
if (ui_to_use_ == UiToUse::kQuietUi)
reason = QuietUiReason::kEnabledInPrefs;
if (async_) { if (async_) {
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), ui_to_use_, reason)); FROM_HERE, base::BindOnce(std::move(callback), decision));
} else { } else {
std::move(callback).Run(ui_to_use_, reason); std::move(callback).Run(decision);
} }
} }
static void CreateForManager(PermissionRequestManager* manager, static void CreateForManager(PermissionRequestManager* manager,
UiToUse ui_to_use, base::Optional<QuietUiReason> quiet_ui_reason,
bool async) { bool async) {
manager->set_notification_permission_ui_selector_for_testing( manager->set_notification_permission_ui_selector_for_testing(
std::make_unique<MockNotificationPermissionUiSelector>(ui_to_use, std::make_unique<MockNotificationPermissionUiSelector>(quiet_ui_reason,
async)); async));
} }
private: private:
UiToUse ui_to_use_; base::Optional<QuietUiReason> quiet_ui_reason_;
bool async_; bool async_;
}; };
...@@ -576,7 +580,8 @@ TEST_F(PermissionRequestManagerTest, ...@@ -576,7 +580,8 @@ TEST_F(PermissionRequestManagerTest,
UiSelectorNotUsedForPermissionsOtherThanNotification) { UiSelectorNotUsedForPermissionsOtherThanNotification) {
for (auto* request : {&request_mic_, &request_camera_, &request_ptz_}) { for (auto* request : {&request_mic_, &request_camera_, &request_ptz_}) {
MockNotificationPermissionUiSelector::CreateForManager( MockNotificationPermissionUiSelector::CreateForManager(
manager_, NotificationPermissionUiSelector::UiToUse::kQuietUi, manager_,
NotificationPermissionUiSelector::QuietUiReason::kEnabledInPrefs,
false /* async */); false /* async */);
manager_->AddRequest(request); manager_->AddRequest(request);
...@@ -593,20 +598,20 @@ TEST_F(PermissionRequestManagerTest, ...@@ -593,20 +598,20 @@ TEST_F(PermissionRequestManagerTest,
} }
TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) { TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) {
using UiToUse = NotificationPermissionUiSelector::UiToUse;
const struct { const struct {
NotificationPermissionUiSelector::UiToUse ui_to_use; base::Optional<NotificationPermissionUiSelector::QuietUiReason>
quiet_ui_reason;
bool async; bool async;
} kTests[] = { } kTests[] = {
{UiToUse::kQuietUi, true}, {QuietUiReason::kEnabledInPrefs, true},
{UiToUse::kNormalUi, true}, {NotificationPermissionUiSelector::Decision::UseNormalUi(), true},
{UiToUse::kQuietUi, false}, {QuietUiReason::kEnabledInPrefs, false},
{UiToUse::kNormalUi, false}, {NotificationPermissionUiSelector::Decision::UseNormalUi(), false},
}; };
for (const auto& test : kTests) { for (const auto& test : kTests) {
MockNotificationPermissionUiSelector::CreateForManager( MockNotificationPermissionUiSelector::CreateForManager(
manager_, test.ui_to_use, test.async); manager_, test.quiet_ui_reason, test.async);
MockPermissionRequest request( MockPermissionRequest request(
"foo", PermissionRequestType::PERMISSION_NOTIFICATIONS, "foo", PermissionRequestType::PERMISSION_NOTIFICATIONS,
...@@ -618,7 +623,7 @@ TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) { ...@@ -618,7 +623,7 @@ TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) {
EXPECT_TRUE(prompt_factory_->is_visible()); EXPECT_TRUE(prompt_factory_->is_visible());
EXPECT_TRUE( EXPECT_TRUE(
prompt_factory_->RequestTypeSeen(request.GetPermissionRequestType())); prompt_factory_->RequestTypeSeen(request.GetPermissionRequestType()));
EXPECT_EQ(test.ui_to_use == UiToUse::kQuietUi, EXPECT_EQ(!!test.quiet_ui_reason,
manager_->ShouldCurrentRequestUseQuietUI()); manager_->ShouldCurrentRequestUseQuietUI());
Accept(); Accept();
...@@ -628,9 +633,9 @@ TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) { ...@@ -628,9 +633,9 @@ TEST_F(PermissionRequestManagerTest, UiSelectorUsedForNotifications) {
TEST_F(PermissionRequestManagerTest, TEST_F(PermissionRequestManagerTest,
UiSelectionHappensSeparatelyForEachRequest) { UiSelectionHappensSeparatelyForEachRequest) {
using UiToUse = NotificationPermissionUiSelector::UiToUse; using QuietUiReason = NotificationPermissionUiSelector::QuietUiReason;
MockNotificationPermissionUiSelector::CreateForManager( MockNotificationPermissionUiSelector::CreateForManager(
manager_, UiToUse::kQuietUi, true); manager_, QuietUiReason::kEnabledInPrefs, true);
MockPermissionRequest request1( MockPermissionRequest request1(
"request1", PermissionRequestType::PERMISSION_NOTIFICATIONS, "request1", PermissionRequestType::PERMISSION_NOTIFICATIONS,
PermissionRequestGestureType::GESTURE); PermissionRequestGestureType::GESTURE);
...@@ -643,7 +648,8 @@ TEST_F(PermissionRequestManagerTest, ...@@ -643,7 +648,8 @@ TEST_F(PermissionRequestManagerTest,
"request2", PermissionRequestType::PERMISSION_NOTIFICATIONS, "request2", PermissionRequestType::PERMISSION_NOTIFICATIONS,
PermissionRequestGestureType::GESTURE); PermissionRequestGestureType::GESTURE);
MockNotificationPermissionUiSelector::CreateForManager( MockNotificationPermissionUiSelector::CreateForManager(
manager_, UiToUse::kNormalUi, true); manager_, NotificationPermissionUiSelector::Decision::UseNormalUi(),
true);
manager_->AddRequest(&request2); manager_->AddRequest(&request2);
WaitForBubbleToBeShown(); WaitForBubbleToBeShown();
EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI()); EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
......
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