| // 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 |