blob: d89b16ea57bda6149d976dd056ecf95f71f4cb0c [file] [log] [blame]
// Copyright 2022 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/unused_site_permissions_service.h"
#include <ctime>
#include <list>
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/time/clock.h"
#include "base/values.h"
#include "components/content_settings/core/browser/content_settings_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_constraints.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/features.h"
#include "components/permissions/constants.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/test/test_render_view_host.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace permissions {
class UnusedSitePermissionsServiceTest
: public content::RenderViewHostTestHarness {
public:
void SetUp() override {
content::RenderViewHostTestHarness::SetUp();
base::Time time;
ASSERT_TRUE(base::Time::FromString("2022-09-07 13:00", &time));
clock_.SetNow(time);
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
hcsm_ = base::MakeRefCounted<HostContentSettingsMap>(&prefs_, false, true,
false, false);
hcsm_->SetClockForTesting(&clock_);
service_ = std::make_unique<UnusedSitePermissionsService>(hcsm_.get());
service_->SetClockForTesting(&clock_);
}
void TearDown() override {
service_->Shutdown();
hcsm_->ShutdownOnUIThread();
content::RenderViewHostTestHarness::TearDown();
}
base::SimpleTestClock* clock() { return &clock_; }
UnusedSitePermissionsService* service() { return service_.get(); }
HostContentSettingsMap* hcsm() { return hcsm_.get(); }
base::Time GetLastVisitedDate(GURL url, ContentSettingsType type) {
content_settings::SettingInfo info;
hcsm()->GetWebsiteSetting(url, url, type, &info);
return info.metadata.last_visited;
}
ContentSettingsForOneType GetRevokedUnusedPermissions(
HostContentSettingsMap* hcsm) {
ContentSettingsForOneType settings;
hcsm->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, &settings);
return settings;
}
base::Value::List GetRevokedPermissionsForOneOrigin(
HostContentSettingsMap* hcsm,
const GURL& url) {
base::Value setting_value(hcsm->GetWebsiteSetting(
url, url, ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
nullptr));
base::Value::List permissions_list;
if (!setting_value.is_dict() ||
!setting_value.GetDict().FindList(permissions::kRevokedKey)) {
return permissions_list;
}
permissions_list =
std::move(*setting_value.GetDict().FindList(permissions::kRevokedKey));
return permissions_list;
}
private:
sync_preferences::TestingPrefServiceSyncable prefs_;
std::unique_ptr<UnusedSitePermissionsService> service_;
scoped_refptr<HostContentSettingsMap> hcsm_;
base::SimpleTestClock clock_;
};
TEST_F(UnusedSitePermissionsServiceTest, UnusedSitePermissionsServiceTest) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url1("https://example1.com");
const GURL url2("https://example2.com");
const ContentSettingsType type1 = ContentSettingsType::GEOLOCATION;
const ContentSettingsType type2 = ContentSettingsType::MEDIASTREAM_CAMERA;
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
const base::Time now = clock()->Now();
const base::TimeDelta precision =
content_settings::GetCoarseVisitedTimePrecision();
// Add one setting for url1 and two settings for url2.
hcsm()->SetContentSettingDefaultScope(
url1, url1, type1, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
url2, url2, type1, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
url2, url2, type2, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 0u);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel through time for 20 days.
clock()->Advance(base::Days(20));
base::Time future = clock()->Now();
// The old settings should now be tracked as unused.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 3u);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Visit url2 and check that the corresponding content setting got updated.
UnusedSitePermissionsService::TabHelper::CreateForWebContents(web_contents(),
service());
NavigateAndCommit(url2);
EXPECT_LE(GetLastVisitedDate(url1, type1), now);
EXPECT_GE(GetLastVisitedDate(url1, type1), now - precision);
EXPECT_LE(GetLastVisitedDate(url2, type1), future);
EXPECT_GE(GetLastVisitedDate(url2, type1), future - precision);
EXPECT_LE(GetLastVisitedDate(url2, type2), future);
EXPECT_GE(GetLastVisitedDate(url2, type2), future - precision);
// Check that the service is only tracking one entry now.
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 1u);
// Travel through time for 50 days to make permissions be revoked.
clock()->Advance(base::Days(50));
// Unused permissions should be auto revoked.
service()->UpdateUnusedPermissionsForTesting();
// url2 should be on tracked permissions list.
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 2u);
std::string url2_str =
ContentSettingsPattern::FromURLNoWildcard(url2).ToString();
EXPECT_EQ(url2_str, service()
->GetTrackedUnusedPermissionsForTesting()[0]
.source.primary_pattern.ToString());
EXPECT_EQ(url2_str, service()
->GetTrackedUnusedPermissionsForTesting()[1]
.source.primary_pattern.ToString());
// url1 should be on revoked permissions list.
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 1u);
std::string url1_str =
ContentSettingsPattern::FromURLNoWildcard(url1).ToString();
EXPECT_EQ(url1_str,
GetRevokedUnusedPermissions(hcsm())[0].primary_pattern.ToString());
}
TEST_F(UnusedSitePermissionsServiceTest, TrackOnlySingleOriginTest) {
const GURL url1("https://example1.com");
const GURL url2("https://[*.]example2.com");
const GURL url3("file:///foo/bar.txt");
const ContentSettingsType type = ContentSettingsType::GEOLOCATION;
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
// Add one setting for all urls.
hcsm()->SetContentSettingDefaultScope(
url1, url1, type, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
url2, url2, type, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
url2, url3, type, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 0u);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel through time for 20 days.
clock()->Advance(base::Days(20));
// Only url1 should be tracked because it is the only single origin url.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 1u);
auto tracked_origin = service()->GetTrackedUnusedPermissionsForTesting()[0];
EXPECT_EQ(GURL(tracked_origin.source.primary_pattern.ToString()), url1);
}
TEST_F(UnusedSitePermissionsServiceTest, TrackUnusedButDontRevoke) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url("https://example1.com");
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
// Grant GEOLOCATION permission for the url.
hcsm()->SetContentSettingDefaultScope(
url, url, ContentSettingsType::GEOLOCATION,
ContentSetting::CONTENT_SETTING_BLOCK, constraint);
// Travel through time for 20 days.
clock()->Advance(base::Days(20));
// GEOLOCATION permission should be on the tracked unused site permissions
// list as it is denied 20 days before. The permission is not suitable for
// revocation and this test verifies that RevokeUnusedPermissions() does not
// enter infinite loop in such case.
service()->UpdateUnusedPermissionsForTesting();
auto unused_permissions = service()->GetTrackedUnusedPermissionsForTesting();
ASSERT_EQ(unused_permissions.size(), 1u);
EXPECT_EQ(unused_permissions[0].type, ContentSettingsType::GEOLOCATION);
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 0u);
}
TEST_F(UnusedSitePermissionsServiceTest, SecondaryPatternAlwaysWildcard) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const ContentSettingsType types[] = {
ContentSettingsType::GEOLOCATION,
ContentSettingsType::AUTOMATIC_DOWNLOADS};
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
// Test combinations of a single origin |primary_pattern| and different
// |secondary_pattern|s: equal to primary pattern, different single origin
// pattern, with domain with wildcard, wildcard.
for (const auto type : types) {
hcsm()->SetContentSettingDefaultScope(
GURL("https://example1.com"), GURL("https://example1.com"), type,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
GURL("https://example2.com"), GURL("https://example3.com"), type,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
GURL("https://example3.com"), GURL("https://[*.]example1.com"), type,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(
GURL("https://example4.com"), GURL("*"), type,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
}
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel through time for 70 days so that permissions are revoked.
clock()->Advance(base::Days(70));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 4u);
for (auto unused_permission : GetRevokedUnusedPermissions(hcsm())) {
EXPECT_EQ(unused_permission.secondary_pattern,
ContentSettingsPattern::Wildcard());
}
}
TEST_F(UnusedSitePermissionsServiceTest, MultipleRevocationsForSameOrigin) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url("https://example1.com");
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
// Grant GEOLOCATION permission for the url.
hcsm()->SetContentSettingDefaultScope(
url, url, ContentSettingsType::GEOLOCATION,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 0u);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel through time for 20 days.
clock()->Advance(base::Days(20));
// Grant MEDIASTREAM_CAMERA permission for the url.
hcsm()->SetContentSettingDefaultScope(
url, url, ContentSettingsType::MEDIASTREAM_CAMERA,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
// GEOLOCATION permission should be on the tracked unused site permissions
// list as it is granted 20 days before. MEDIASTREAM_CAMERA permission should
// not be tracked as it is just granted.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 1u);
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting()[0].type,
ContentSettingsType::GEOLOCATION);
// Travel through time for 50 days.
clock()->Advance(base::Days(50));
// GEOLOCATION permission should be on the revoked permissions list as it is
// granted 70 days before. MEDIASTREAM_CAMERA permission should be on the
// recently unused permissions list as it is granted 50 days before.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 1u);
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url)[0].GetInt(),
static_cast<int32_t>(ContentSettingsType::GEOLOCATION));
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 1u);
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting()[0].type,
ContentSettingsType::MEDIASTREAM_CAMERA);
// Travel through time for 20 days.
clock()->Advance(base::Days(20));
// Both GEOLOCATION and MEDIASTREAM_CAMERA permissions should be on the
// revoked permissions list as they are granted more than 60 days before.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 2u);
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url)[0].GetInt(),
static_cast<int32_t>(ContentSettingsType::GEOLOCATION));
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url)[1].GetInt(),
static_cast<int32_t>(ContentSettingsType::MEDIASTREAM_CAMERA));
// Travel through time for 30 days.
clock()->Advance(base::Days(30));
// No permission should be on the revoked permissions list as they are revoked
// more than 30 days before.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 0u);
}
TEST_F(UnusedSitePermissionsServiceTest, RegrantPermissionsForOrigin) {
const std::string url1 = "https://example1.com:443";
const std::string url2 = "https://example2.com:443";
const ContentSettingsType type = ContentSettingsType::GEOLOCATION;
base::Value::Dict dict = base::Value::Dict();
base::Value::List permission_type_list = base::Value::List();
permission_type_list.Append(static_cast<int32_t>(type));
dict.Set(kRevokedKey, base::Value::List(std::move(permission_type_list)));
// Add url1 and url2 to revoked permissions list.
hcsm()->SetWebsiteSettingDefaultScope(
GURL(url1), GURL(url1),
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
base::Value(dict.Clone()));
hcsm()->SetWebsiteSettingDefaultScope(
GURL(url2), GURL(url2),
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
base::Value(dict.Clone()));
// Check there are 2 origin in revoked permissions list.
ContentSettingsForOneType revoked_permissions_list;
hcsm()->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
&revoked_permissions_list);
EXPECT_EQ(2U, revoked_permissions_list.size());
// Allow the permission for url1 again
service()->RegrantPermissionsForOrigin(url::Origin::Create(GURL(url1)));
// Check there is only url2 in revoked permissions list.
hcsm()->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
&revoked_permissions_list);
EXPECT_EQ(1U, revoked_permissions_list.size());
// Check if the permissions of url1 is regranted.
EXPECT_EQ(ContentSetting::CONTENT_SETTING_ALLOW,
hcsm()->GetContentSetting(GURL(url1), GURL(url1), type));
// Undoing the changes should add url1 back to the list of revoked permissions
// and reset its permissions.
service()->UndoRegrantPermissionsForOrigin({type}, absl::nullopt,
url::Origin::Create(GURL(url1)));
hcsm()->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
&revoked_permissions_list);
EXPECT_EQ(2U, revoked_permissions_list.size());
EXPECT_EQ(ContentSetting::CONTENT_SETTING_ASK,
hcsm()->GetContentSetting(GURL(url1), GURL(url1), type));
}
TEST_F(UnusedSitePermissionsServiceTest, RegrantPreventsAutorevoke) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url1 = GURL("https://example1.com:443");
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
hcsm()->SetContentSettingDefaultScope(
url1, url1, ContentSettingsType::GEOLOCATION,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel 70 days through time so that the granted permission is revoked.
clock()->Advance(base::Days(70));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 1u);
// After regranting permissions they are not revoked again even after >60 days
// pass.
service()->RegrantPermissionsForOrigin(url::Origin::Create(url1));
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
clock()->Advance(base::Days(70));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
}
TEST_F(UnusedSitePermissionsServiceTest, UndoRegrantPermissionsForOrigin) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url1 = GURL("https://example1.com:443");
const ContentSettingsType type = ContentSettingsType::GEOLOCATION;
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
hcsm()->SetContentSettingDefaultScope(
url1, url1, type, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel 70 days through time so that the granted permission is revoked.
clock()->Advance(base::Days(70));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 1u);
const ContentSettingPatternSource revoked_permission =
GetRevokedUnusedPermissions(hcsm())[0];
// Permission remains revoked after regrant and undo.
content_settings::ContentSettingConstraints expiration_constraint = {
.expiration = revoked_permission.metadata.expiration};
service()->RegrantPermissionsForOrigin(url::Origin::Create(url1));
service()->UndoRegrantPermissionsForOrigin({type}, expiration_constraint,
url::Origin::Create(url1));
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 1u);
// Revoked permission is cleaned up after >30 days.
clock()->Advance(base::Days(40));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// If that permission is granted again, it will still be autorevoked.
hcsm()->SetContentSettingDefaultScope(
url1, url1, type, ContentSetting::CONTENT_SETTING_ALLOW, constraint);
clock()->Advance(base::Days(70));
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 1u);
}
TEST_F(UnusedSitePermissionsServiceTest, NotRevokeNotificationPermission) {
base::test::ScopedFeatureList scoped_feature;
scoped_feature.InitAndEnableFeature(
content_settings::features::kSafetyCheckUnusedSitePermissions);
const GURL url("https://example1.com");
const content_settings::ContentSettingConstraints constraint{
.track_last_visit_for_autoexpiration = true};
// Grant GEOLOCATION and NOTIFICATION permission for the url.
hcsm()->SetContentSettingDefaultScope(
url, url, ContentSettingsType::GEOLOCATION,
ContentSetting::CONTENT_SETTING_ALLOW, constraint);
hcsm()->SetContentSettingDefaultScope(url, url,
ContentSettingsType::NOTIFICATIONS,
ContentSetting::CONTENT_SETTING_ALLOW);
EXPECT_EQ(service()->GetTrackedUnusedPermissionsForTesting().size(), 0u);
EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 0u);
// Travel through time for 70 days.
clock()->Advance(base::Days(70));
// GEOLOCATION permission should be on the revoked permissions list, but
// NOTIFICATION permissions should not be as notification permissions are out
// of scope.
service()->UpdateUnusedPermissionsForTesting();
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 1u);
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url)[0].GetInt(),
static_cast<int32_t>(ContentSettingsType::GEOLOCATION));
// Clearing revoked permissions list should delete unused GEOLOCATION from it
// but leave used NOTIFICATION permissions intact.
service()->ClearRevokedPermissionsList();
EXPECT_EQ(GetRevokedPermissionsForOneOrigin(hcsm(), url).size(), 0u);
EXPECT_EQ(hcsm()->GetContentSetting(GURL(url), GURL(url),
ContentSettingsType::GEOLOCATION),
ContentSetting::CONTENT_SETTING_ASK);
EXPECT_EQ(hcsm()->GetContentSetting(GURL(url), GURL(url),
ContentSettingsType::NOTIFICATIONS),
ContentSetting::CONTENT_SETTING_ALLOW);
}
TEST_F(UnusedSitePermissionsServiceTest, ClearRevokedPermissionsList) {
const std::string url1 = "https://example1.com:443";
const std::string url2 = "https://example2.com:443";
const ContentSettingsType type = ContentSettingsType::GEOLOCATION;
base::Value::Dict dict = base::Value::Dict();
base::Value::List permission_type_list = base::Value::List();
permission_type_list.Append(static_cast<int32_t>(type));
dict.Set(kRevokedKey, base::Value::List(std::move(permission_type_list)));
// Add url1 and url2 to revoked permissions list.
hcsm()->SetWebsiteSettingDefaultScope(
GURL(url1), GURL(url1),
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
base::Value(dict.Clone()));
hcsm()->SetWebsiteSettingDefaultScope(
GURL(url2), GURL(url2),
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
base::Value(dict.Clone()));
// Check there are 2 origins in the revoked permissions list.
ContentSettingsForOneType revoked_permissions_list;
hcsm()->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
&revoked_permissions_list);
EXPECT_EQ(2U, revoked_permissions_list.size());
service()->ClearRevokedPermissionsList();
// Revoked permissions list should be empty.
hcsm()->GetSettingsForOneType(
ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS,
&revoked_permissions_list);
EXPECT_EQ(revoked_permissions_list.size(), 0U);
}
} // namespace permissions