Commit 8f17b5e1 authored by Andy Paicu's avatar Andy Paicu Committed by Chromium LUCI CQ

Added a command line switch to mock a prediction service response

This is needed in order to facilitate testing the feature.

Bug: 1138595,1155511
Change-Id: Ib01969e48e5686b3ffed963745c5e85a1d802221
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2573076
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#834267}
parent 45a38907
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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 "chrome/browser/permissions/prediction_based_permission_ui_selector.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/time/default_clock.h"
#include "base/util/values/values_util.h"
......@@ -11,6 +12,7 @@
#include "chrome/browser/permissions/prediction_service_request.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/prediction_service/prediction_service.h"
......@@ -23,7 +25,7 @@ namespace {
using QuietUiReason = PredictionBasedPermissionUiSelector::QuietUiReason;
using Decision = PredictionBasedPermissionUiSelector::Decision;
const auto VeryUnlikely = permissions::
constexpr auto VeryUnlikely = permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_VERY_UNLIKELY;
// The data we consider can only be at most 28 days old to match the data that
......@@ -34,11 +36,48 @@ constexpr base::TimeDelta kPermissionActionCutoffAge =
constexpr char kPermissionActionEntryActionKey[] = "action";
constexpr char kPermissionActionEntryTimestampKey[] = "time";
base::Optional<
permissions::PermissionSuggestion_Likelihood_DiscretizedLikelihood>
ParsePredictionServiceMockLikelihood(const std::string& value) {
if (value == "very-unlikely") {
return permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_VERY_UNLIKELY;
} else if (value == "unlikely") {
return permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_UNLIKELY;
} else if (value == "neutral") {
return permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_NEUTRAL;
} else if (value == "likely") {
return permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_LIKELY;
} else if (value == "very-likely") {
return permissions::
PermissionSuggestion_Likelihood_DiscretizedLikelihood_VERY_LIKELY;
}
return base::nullopt;
}
bool ShouldPredictionTriggerQuietUi(
permissions::PermissionUmaUtil::PredictionGrantLikelihood likelihood) {
return likelihood == VeryUnlikely;
}
} // namespace
PredictionBasedPermissionUiSelector::PredictionBasedPermissionUiSelector(
Profile* profile)
: profile_(profile) {}
: profile_(profile) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kPredictionServiceMockLikelihood)) {
auto mock_likelihood = ParsePredictionServiceMockLikelihood(
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kPredictionServiceMockLikelihood));
if (mock_likelihood.has_value())
set_likelihood_override(mock_likelihood.value());
}
}
PredictionBasedPermissionUiSelector::~PredictionBasedPermissionUiSelector() =
default;
......@@ -51,6 +90,18 @@ void PredictionBasedPermissionUiSelector::SelectUiToUse(
return;
}
if (likelihood_override_for_testing_.has_value()) {
if (ShouldPredictionTriggerQuietUi(
likelihood_override_for_testing_.value())) {
std::move(callback).Run(
Decision(QuietUiReason::kPredictedVeryUnlikelyGrant,
Decision::ShowNoWarning()));
} else {
std::move(callback).Run(Decision::UseNormalUiAndShowNoWarning());
}
return;
}
last_request_grant_likelihood_ = base::nullopt;
DCHECK(!request_);
......@@ -139,8 +190,7 @@ void PredictionBasedPermissionUiSelector::LookupReponseReceived(
last_request_grant_likelihood_ =
response->suggestion(0).grant_likelihood().discretized_likelihood();
if (response->suggestion(0).grant_likelihood().discretized_likelihood() ==
VeryUnlikely) {
if (ShouldPredictionTriggerQuietUi(last_request_grant_likelihood_.value())) {
std::move(callback_).Run(Decision(
QuietUiReason::kPredictedVeryUnlikelyGrant, Decision::ShowNoWarning()));
return;
......
......@@ -23,6 +23,8 @@ class GetSuggestionsResponse;
class PredictionBasedPermissionUiSelector
: public permissions::NotificationPermissionUiSelector {
public:
using PredictionGrantLikelihood =
permissions::PermissionUmaUtil::PredictionGrantLikelihood;
// Constructs an instance in the context of the given |profile|.
explicit PredictionBasedPermissionUiSelector(Profile* profile);
~PredictionBasedPermissionUiSelector() override;
......@@ -38,8 +40,8 @@ class PredictionBasedPermissionUiSelector
void Cancel() override;
base::Optional<permissions::PermissionUmaUtil::PredictionGrantLikelihood>
PredictedGrantLikelihoodForUKM() override;
base::Optional<PredictionGrantLikelihood> PredictedGrantLikelihoodForUKM()
override;
private:
permissions::PredictionRequestFeatures BuildPredictionRequestFeatures(
......@@ -50,10 +52,15 @@ class PredictionBasedPermissionUiSelector
std::unique_ptr<permissions::GetSuggestionsResponse> response);
bool IsAllowedToUseAssistedPrompts();
void set_likelihood_override(PredictionGrantLikelihood mock_likelihood) {
likelihood_override_for_testing_ = mock_likelihood;
}
Profile* profile_;
std::unique_ptr<PredictionServiceRequest> request_;
base::Optional<permissions::PermissionUmaUtil::PredictionGrantLikelihood>
last_request_grant_likelihood_;
base::Optional<PredictionGrantLikelihood> last_request_grant_likelihood_;
base::Optional<PredictionGrantLikelihood> likelihood_override_for_testing_;
DecisionMadeCallback callback_;
};
......
// 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 "chrome/browser/permissions/prediction_based_permission_ui_selector.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_profile.h"
#include "components/permissions/test/mock_permission_request.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using Decision = PredictionBasedPermissionUiSelector::Decision;
} // namespace
class PredictionBasedPermissionUiSelectorTest : public testing::Test {
public:
PredictionBasedPermissionUiSelectorTest()
: testing_profile_(std::make_unique<TestingProfile>()) {}
void SetUp() override {
feature_list_.InitWithFeatures(
{features::kQuietNotificationPrompts, features::kPermissionPredictions},
{});
safe_browsing::SetSafeBrowsingState(
testing_profile_->GetPrefs(),
safe_browsing::SafeBrowsingState::ENHANCED_PROTECTION);
}
TestingProfile* profile() { return testing_profile_.get(); }
Decision SelectUiToUseAndGetDecision(
PredictionBasedPermissionUiSelector* selector) {
base::Optional<Decision> actual_decision;
base::RunLoop run_loop;
permissions::MockPermissionRequest request(
"request", permissions::PermissionRequestType::PERMISSION_NOTIFICATIONS,
permissions::PermissionRequestGestureType::GESTURE);
selector->SelectUiToUse(
&request, base::BindLambdaForTesting([&](const Decision& decision) {
actual_decision = decision;
run_loop.Quit();
}));
run_loop.Run();
return actual_decision.value();
}
private:
content::BrowserTaskEnvironment task_environment_;
base::test::ScopedFeatureList feature_list_;
std::unique_ptr<TestingProfile> testing_profile_;
};
TEST_F(PredictionBasedPermissionUiSelectorTest,
CommandLineMocksDecisionCorrectly) {
struct {
const char* command_line_value;
const Decision expected_decision;
} const kTests[] = {
{"very-unlikely", Decision(PredictionBasedPermissionUiSelector::
QuietUiReason::kPredictedVeryUnlikelyGrant,
Decision::ShowNoWarning())},
{"unlikely", Decision::UseNormalUiAndShowNoWarning()},
{"neutral", Decision::UseNormalUiAndShowNoWarning()},
{"likely", Decision::UseNormalUiAndShowNoWarning()},
{"very-likely", Decision::UseNormalUiAndShowNoWarning()},
};
for (const auto& test : kTests) {
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
"prediction-service-mock-likelihood", test.command_line_value);
PredictionBasedPermissionUiSelector prediction_selector(profile());
Decision decision = SelectUiToUseAndGetDecision(&prediction_selector);
EXPECT_EQ(test.expected_decision.quiet_ui_reason, decision.quiet_ui_reason);
EXPECT_EQ(test.expected_decision.warning_reason, decision.warning_reason);
}
}
......@@ -429,6 +429,11 @@ const char kPermissionRequestApiScope[] = "permission-request-api-scope";
// TODO(bauerb): Remove when this flag is not needed anymore.
const char kPermissionRequestApiUrl[] = "permission-request-api-url";
// Used to mock the response received from the Web Permission Prediction
// Service. Used for testing.
const char kPredictionServiceMockLikelihood[] =
"prediction-service-mock-likelihood";
// Use IPv6 only for privet HTTP.
const char kPrivetIPv6Only[] = "privet-ipv6-only";
......
......@@ -136,6 +136,7 @@ extern const char kPackExtension[];
extern const char kPackExtensionKey[];
extern const char kPermissionRequestApiScope[];
extern const char kPermissionRequestApiUrl[];
extern const char kPredictionServiceMockLikelihood[];
extern const char kPrivetIPv6Only[];
extern const char kProductVersion[];
extern const char kProfileDirectory[];
......
......@@ -3603,6 +3603,7 @@ test("unit_tests") {
"../browser/permissions/crowd_deny_preload_data_unittest.cc",
"../browser/permissions/crowd_deny_safe_browsing_request_unittest.cc",
"../browser/permissions/permission_context_base_feature_policy_unittest.cc",
"../browser/permissions/prediction_based_permission_ui_selector_unittest.cc",
"../browser/permissions/pref_notification_permission_ui_selector_unittest.cc",
"../browser/persisted_state_db/persisted_state_db_factory_unittest.cc",
"../browser/persisted_state_db/persisted_state_db_unittest.cc",
......
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