blob: 2a49c7fd4f855e0a7046f388e0e7fc370e82a134 [file] [log] [blame]
// Copyright 2016 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/permission_uma_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/test/metrics/histogram_tester.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/permissions/test/test_permissions_client.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_browser_context.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace permissions {
class PermissionUmaUtilTest : public testing::Test {
private:
content::BrowserTaskEnvironment task_environment_;
TestPermissionsClient permissions_client_;
};
TEST_F(PermissionUmaUtilTest, ScopedRevocationReporter) {
content::TestBrowserContext browser_context;
// TODO(tsergeant): Add more comprehensive tests of PermissionUmaUtil.
base::HistogramTester histograms;
HostContentSettingsMap* map =
PermissionsClient::Get()->GetSettingsMap(&browser_context);
GURL host("https://example.com");
ContentSettingsPattern host_pattern =
ContentSettingsPattern::FromURLNoWildcard(host);
ContentSettingsPattern host_containing_wildcards_pattern =
ContentSettingsPattern::FromString("https://[*.]example.com/");
ContentSettingsType type = ContentSettingsType::GEOLOCATION;
PermissionSourceUI source_ui = PermissionSourceUI::SITE_SETTINGS;
// Allow->Block triggers a revocation.
map->SetContentSettingDefaultScope(host, host, type, CONTENT_SETTING_ALLOW);
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host, host, type, source_ui);
map->SetContentSettingDefaultScope(host, host, type, CONTENT_SETTING_BLOCK);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 1);
// Block->Allow does not trigger a revocation.
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host, host, type, source_ui);
map->SetContentSettingDefaultScope(host, host, type, CONTENT_SETTING_ALLOW);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 1);
// Allow->Default triggers a revocation when default is 'ask'.
map->SetDefaultContentSetting(type, CONTENT_SETTING_ASK);
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host, host, type, source_ui);
map->SetContentSettingDefaultScope(host, host, type,
CONTENT_SETTING_DEFAULT);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 2);
// Allow->Default does not trigger a revocation when default is 'allow'.
map->SetDefaultContentSetting(type, CONTENT_SETTING_ALLOW);
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host, host, type, source_ui);
map->SetContentSettingDefaultScope(host, host, type,
CONTENT_SETTING_DEFAULT);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 2);
// Allow->Block with url pattern string triggers a revocation.
map->SetContentSettingDefaultScope(host, host, type, CONTENT_SETTING_ALLOW);
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host_pattern, host_pattern, type, source_ui);
map->SetContentSettingCustomScope(host_pattern,
ContentSettingsPattern::Wildcard(), type,
CONTENT_SETTING_BLOCK);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 3);
// Allow->Block with non url pattern string does not trigger a revocation.
map->SetContentSettingDefaultScope(host, host, type, CONTENT_SETTING_ALLOW);
{
PermissionUmaUtil::ScopedRevocationReporter scoped_revocation_reporter(
&browser_context, host_containing_wildcards_pattern, host_pattern, type,
source_ui);
map->SetContentSettingCustomScope(host_containing_wildcards_pattern,
ContentSettingsPattern::Wildcard(), type,
CONTENT_SETTING_BLOCK);
}
histograms.ExpectBucketCount("Permissions.Action.Geolocation",
static_cast<int>(PermissionAction::REVOKED), 3);
}
TEST_F(PermissionUmaUtilTest, CrowdDenyVersionTest) {
base::HistogramTester histograms;
const absl::optional<base::Version> empty_version;
PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(empty_version);
histograms.ExpectBucketCount(
"Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime", 0, 1);
const absl::optional<base::Version> valid_version =
base::Version({2020, 10, 11, 1234});
PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(valid_version);
histograms.ExpectBucketCount(
"Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime", 20201011, 1);
const absl::optional<base::Version> valid_old_version =
base::Version({2019, 10, 10, 1234});
PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(valid_old_version);
histograms.ExpectBucketCount(
"Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime", 1, 1);
const absl::optional<base::Version> valid_future_version =
base::Version({2021, 1, 1, 1234});
PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(
valid_future_version);
histograms.ExpectBucketCount(
"Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime", 20210101, 1);
const absl::optional<base::Version> invalid_version =
base::Version({2020, 10, 11});
PermissionUmaUtil::RecordCrowdDenyVersionAtAbuseCheckTime(valid_version);
histograms.ExpectBucketCount(
"Permissions.CrowdDeny.PreloadData.VersionAtAbuseCheckTime", 1, 1);
}
// Test that the appropriate UMA metrics have been recorded when the DSE is
// disabled.
TEST_F(PermissionUmaUtilTest, MetricsAreRecordedWhenAutoDSEPermissionReverted) {
const std::string kTransitionHistogramPrefix =
"Permissions.DSE.AutoPermissionRevertTransition.";
const std::string kInvalidTransitionHistogramPrefix =
"Permissions.DSE.InvalidAutoPermissionRevertTransition.";
constexpr struct {
ContentSetting backed_up_setting;
ContentSetting effective_setting;
ContentSetting end_state_setting;
permissions::AutoDSEPermissionRevertTransition expected_transition;
} kTests[] = {
// Expected valid combinations.
{CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK,
permissions::AutoDSEPermissionRevertTransition::NO_DECISION_ASK},
{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW,
permissions::AutoDSEPermissionRevertTransition::PRESERVE_ALLOW},
{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK,
permissions::AutoDSEPermissionRevertTransition::CONFLICT_ASK},
{CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK,
permissions::AutoDSEPermissionRevertTransition::PRESERVE_BLOCK_ASK},
{CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK,
permissions::AutoDSEPermissionRevertTransition::PRESERVE_BLOCK_ALLOW},
{CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK,
permissions::AutoDSEPermissionRevertTransition::PRESERVE_BLOCK_BLOCK},
// Invalid combinations.
{CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK,
permissions::AutoDSEPermissionRevertTransition::INVALID_END_STATE},
{CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW,
permissions::AutoDSEPermissionRevertTransition::INVALID_END_STATE},
{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
permissions::AutoDSEPermissionRevertTransition::INVALID_END_STATE},
{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW,
permissions::AutoDSEPermissionRevertTransition::INVALID_END_STATE},
};
// We test every combination of test case for notifications and geolocation to
// basically test the entire possible transition space.
for (const auto& test : kTests) {
for (const auto type : {ContentSettingsType::NOTIFICATIONS,
ContentSettingsType::GEOLOCATION}) {
const std::string type_string = type == ContentSettingsType::NOTIFICATIONS
? "Notifications"
: "Geolocation";
base::HistogramTester histograms;
PermissionUmaUtil::RecordAutoDSEPermissionReverted(
type, test.backed_up_setting, test.effective_setting,
test.end_state_setting);
// Test that the expected samples are recorded in histograms.
histograms.ExpectBucketCount(kTransitionHistogramPrefix + type_string,
test.expected_transition, 1);
histograms.ExpectTotalCount(kTransitionHistogramPrefix + type_string, 1);
if (test.expected_transition ==
permissions::AutoDSEPermissionRevertTransition::INVALID_END_STATE) {
// If INVALID_END_STATE is recorded, there should be more histograms.
const std::string backed_up_histogram =
kInvalidTransitionHistogramPrefix + "BackedUpSetting." +
type_string;
const std::string effective_histogram =
kInvalidTransitionHistogramPrefix + "EffectiveSetting." +
type_string;
const std::string end_state_histogram =
kInvalidTransitionHistogramPrefix + "EndStateSetting." +
type_string;
histograms.ExpectBucketCount(backed_up_histogram,
test.backed_up_setting, 1);
histograms.ExpectBucketCount(effective_histogram,
test.effective_setting, 1);
histograms.ExpectBucketCount(end_state_histogram,
test.end_state_setting, 1);
histograms.ExpectTotalCount(backed_up_histogram, 1);
histograms.ExpectTotalCount(effective_histogram, 1);
histograms.ExpectTotalCount(end_state_histogram, 1);
} else {
EXPECT_EQ(base::HistogramTester::CountsMap(),
histograms.GetTotalCountsForPrefix(
"Permissions.DSE.InvalidAutoPermissionRevertTransition"));
}
}
}
}
} // namespace permissions