123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864 |
- // 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_decision_auto_blocker.h"
- #include <map>
- #include <memory>
- #include "base/bind.h"
- #include "base/run_loop.h"
- #include "base/test/gtest_util.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/simple_test_clock.h"
- #include "components/permissions/features.h"
- #include "components/permissions/permission_util.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"
- namespace permissions {
- namespace {
- bool FilterGoogle(const GURL& url) {
- return url == "https://www.google.com/";
- }
- bool FilterAll(const GURL& url) {
- return true;
- }
- } // namespace
- class PermissionDecisionAutoBlockerUnitTest : public testing::Test {
- protected:
- PermissionDecisionAutoBlockerUnitTest() {
- feature_list_.InitWithFeatures({features::kBlockPromptsIfDismissedOften,
- features::kBlockPromptsIfIgnoredOften},
- {});
- last_embargoed_status_ = false;
- autoblocker()->SetClockForTesting(&clock_);
- callback_was_run_ = false;
- }
- PermissionDecisionAutoBlocker* autoblocker() {
- return PermissionsClient::Get()->GetPermissionDecisionAutoBlocker(
- &browser_context_);
- }
- void SetLastEmbargoStatus(base::OnceClosure quit_closure, bool status) {
- callback_was_run_ = true;
- last_embargoed_status_ = status;
- if (quit_closure) {
- std::move(quit_closure).Run();
- }
- }
- bool last_embargoed_status() { return last_embargoed_status_; }
- bool callback_was_run() { return callback_was_run_; }
- base::SimpleTestClock* clock() { return &clock_; }
- private:
- content::BrowserTaskEnvironment task_environment_;
- base::SimpleTestClock clock_;
- base::test::ScopedFeatureList feature_list_;
- content::TestBrowserContext browser_context_;
- TestPermissionsClient permissions_client_;
- bool last_embargoed_status_;
- bool callback_was_run_;
- };
- // Check removing the the embargo for a single permission on a site works, and
- // that it doesn't interfere with other embargoed permissions or the same
- // permission embargoed on other sites.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoAndResetCounts) {
- GURL url1("https://www.google.com");
- GURL url2("https://www.example.com");
- // Record dismissals for location and notifications in |url1|.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- // Record dismissals for location in |url2|.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- // Verify all dismissals recorded above resulted in embargo.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url1, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- result =
- autoblocker()->GetEmbargoResult(url1, ContentSettingsType::NOTIFICATIONS);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- result =
- autoblocker()->GetEmbargoResult(url2, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Remove the embargo on notifications. Verify it is no longer under embargo,
- // but location still is.
- autoblocker()->RemoveEmbargoAndResetCounts(
- url1, ContentSettingsType::NOTIFICATIONS);
- result =
- autoblocker()->GetEmbargoResult(url1, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- result =
- autoblocker()->GetEmbargoResult(url1, ContentSettingsType::NOTIFICATIONS);
- // If not under embargo, GetEmbargoResult() returns absl::nullopt.
- EXPECT_FALSE(result.has_value());
- // Verify |url2|'s embargo is still intact as well.
- result =
- autoblocker()->GetEmbargoResult(url2, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- }
- // Test it does not take one more dismissal to re-trigger embargo after
- // removing the embargo status for a site.
- TEST_F(PermissionDecisionAutoBlockerUnitTest,
- DismissAfterRemovingEmbargoByURL) {
- GURL url("https://www.example.com");
- // Record dismissals for location.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- // Verify location is under embargo.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Remove embargo and verify this is true.
- autoblocker()->RemoveEmbargoAndResetCounts(url,
- ContentSettingsType::GEOLOCATION);
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Record another dismissal and verify location is not under embargo again.
- autoblocker()->RecordDismissAndEmbargo(url, ContentSettingsType::GEOLOCATION,
- false);
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- }
- TEST_F(PermissionDecisionAutoBlockerUnitTest,
- NonembargoedOriginRemoveEmbargoCounts) {
- GURL gurl_to_embargo("https://www.google.com");
- // Make sure that an origin's Dismiss count is 0.
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION));
- // Dismiss the origin a few times but do not add under embargo.
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
- EXPECT_EQ(2, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION));
- autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
- ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION));
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- EXPECT_EQ(2, autoblocker()->GetIgnoreCount(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX));
- autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX);
- EXPECT_EQ(0, autoblocker()->GetIgnoreCount(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX));
- }
- TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoCounts) {
- GURL gurl_to_embargo("https://www.google.com");
- // Add an origin under embargo for 2 dismissed and 1 ignored
- // ContentSettingsType.
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION, false);
- EXPECT_EQ(3, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION));
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
- autoblocker()->RecordDismissAndEmbargo(
- gurl_to_embargo, ContentSettingsType::NOTIFICATIONS, false);
- EXPECT_EQ(3, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::NOTIFICATIONS));
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- autoblocker()->RecordIgnoreAndEmbargo(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX, false);
- EXPECT_EQ(4, autoblocker()->GetIgnoreCount(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX));
- autoblocker()->RemoveEmbargoAndResetCounts(gurl_to_embargo,
- ContentSettingsType::GEOLOCATION);
- // GEOLOCATION has been cleared, a dismiss count should be 0.
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::GEOLOCATION));
- // GEOLOCATION has been cleared, but other counts should be
- // preservet.
- EXPECT_EQ(3, autoblocker()->GetDismissCount(
- gurl_to_embargo, ContentSettingsType::NOTIFICATIONS));
- EXPECT_EQ(4, autoblocker()->GetIgnoreCount(gurl_to_embargo,
- ContentSettingsType::MIDI_SYSEX));
- }
- TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveEmbargoAndResetCounts_All) {
- GURL url1("https://www.google.com");
- GURL url2("https://www.example.com");
- // Record some dismissals.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(2, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(3, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url2, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- // Record some ignores.
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url1, ContentSettingsType::MIDI_SYSEX, false));
- EXPECT_EQ(
- 1, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::MIDI_SYSEX));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url1, ContentSettingsType::DURABLE_STORAGE, false));
- EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
- url1, ContentSettingsType::DURABLE_STORAGE));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(
- 2, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
- autoblocker()->RemoveEmbargoAndResetCounts(
- base::BindRepeating(&FilterGoogle));
- // Expect that url1's actions are gone, but url2's remain.
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- EXPECT_EQ(
- 0, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::MIDI_SYSEX));
- EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
- url1, ContentSettingsType::DURABLE_STORAGE));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url2, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(
- 2, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
- // Add some more actions.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_EQ(1, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(2, autoblocker()->GetDismissCount(
- url2, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_EQ(
- 1, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::GEOLOCATION));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url1, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url1, ContentSettingsType::DURABLE_STORAGE, false));
- EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
- url1, ContentSettingsType::DURABLE_STORAGE));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url2, ContentSettingsType::MIDI_SYSEX, false));
- EXPECT_EQ(
- 1, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::MIDI_SYSEX));
- // Remove everything and expect that it's all gone.
- autoblocker()->RemoveEmbargoAndResetCounts(base::BindRepeating(&FilterAll));
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- EXPECT_EQ(0, autoblocker()->GetDismissCount(
- url2, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(
- 0, autoblocker()->GetIgnoreCount(url1, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
- url1, ContentSettingsType::NOTIFICATIONS));
- EXPECT_EQ(
- 0, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::GEOLOCATION));
- EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
- url2, ContentSettingsType::DURABLE_STORAGE));
- EXPECT_EQ(
- 0, autoblocker()->GetIgnoreCount(url2, ContentSettingsType::MIDI_SYSEX));
- }
- // Check that GetEmbargoedOrigins only returns origins where embargo is the
- // effective permission enforcement mechanism.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoedOrigins) {
- GURL url1("https://www.google.com");
- GURL url2("https://www.google.com:8443");
- std::vector<ContentSettingsType> content_types = {
- ContentSettingsType::GEOLOCATION, ContentSettingsType::NOTIFICATIONS};
- std::set<GURL> origins;
- clock()->SetNow(base::Time::Now());
- EXPECT_EQ(0UL, autoblocker()->GetEmbargoedOrigins(content_types).size());
- // Place both origins under embargo and verify.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url1, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url2, ContentSettingsType::NOTIFICATIONS, false));
- origins = autoblocker()->GetEmbargoedOrigins(content_types);
- EXPECT_EQ(2UL, origins.size());
- EXPECT_EQ(1UL, origins.count(url1));
- EXPECT_EQ(1UL, origins.count(url2));
- // Check no leakage between content types
- origins =
- autoblocker()->GetEmbargoedOrigins(ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(1UL, origins.count(url1));
- origins =
- autoblocker()->GetEmbargoedOrigins(ContentSettingsType::NOTIFICATIONS);
- EXPECT_EQ(1UL, origins.count(url2));
- // Remove an embargo and confirm it's removed from origins
- autoblocker()->RemoveEmbargoAndResetCounts(url1,
- ContentSettingsType::GEOLOCATION);
- origins = autoblocker()->GetEmbargoedOrigins(content_types);
- EXPECT_EQ(1UL, origins.size());
- EXPECT_EQ(1UL, origins.count(url2));
- // Expire the remaining embargo and confirm the origin is removed
- clock()->Advance(base::Days(8));
- origins = autoblocker()->GetEmbargoedOrigins(content_types);
- EXPECT_EQ(0UL, origins.size());
- }
- // Check that GetEmbargoResult returns the correct value when the embargo is set
- // and expires.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStatus) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- // Check the default state.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Place under embargo and verify.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Check that the origin is not under embargo for a different permission.
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // Confirm embargo status during the embargo period.
- clock()->Advance(base::Days(5));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Check embargo is lifted on expiry day. A small offset after the exact
- // embargo expiration date has been added to account for any precision errors
- // when removing the date stored as a double from the permission dictionary.
- clock()->Advance(base::Hours(3 * 24 + 1));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Check embargo is lifted well after the expiry day.
- clock()->Advance(base::Days(1));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Place under embargo again and verify the embargo status.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, false));
- clock()->Advance(base::Days(1));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- }
- // Check that GetEmbargoStartTime returns the correct time for embargoes whether
- // they are nonexistent, expired or active.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, CheckEmbargoStartTime) {
- GURL url("https://www.google.com");
- // The time recorded for embargoes will be stored as a double, which will
- // cause aliasing to a limited set of base::Time values upon retrieval. We
- // thus pick a base::Time for our test time that is part of this set via
- // aliasing the current time by passing it through a double. This allows us
- // to directly compare the test time and times retrieved from storage.
- base::Time test_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::Microseconds(static_cast<double>(
- base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds())));
- clock()->SetNow(test_time);
- // Check the default non embargod state.
- base::Time embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(base::Time(), embargo_start_time);
- // Ensure that dismissing less than the required number for an embargo
- // does not record an embargo start time.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(base::Time(), embargo_start_time);
- // Place site under geolocation dismissal embargo.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- // Confirm embargo is recorded as starting at the correct time.
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- // Ensure moving clock while within embargo period does not affect embargo
- // start time.
- clock()->Advance(base::Days(5));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- // Move clock beyond embaro (plus a small offset for potential precision
- // errors) and confirm start time is unaffected but embargo is suspended.
- clock()->Advance(base::Hours(3 * 24 + 1));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Advance time, reinstate embargo and confirm that time is updated.
- test_time += base::Days(9);
- test_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::Microseconds(static_cast<double>(
- test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
- clock()->SetNow(test_time);
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- // Advance time to expire dismiss embargo and create new embargo for ignoring.
- test_time += base::Days(7);
- test_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::Microseconds(static_cast<double>(
- test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
- clock()->SetNow(test_time);
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- // Confirm the most recent embargo is updated to match new ignore embargo.
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- // Advance time, reinstate the dismiss embargo via a single action, and
- // confirm that time is updated.
- test_time += base::Days(1);
- test_time = base::Time::FromDeltaSinceWindowsEpoch(
- base::Microseconds(static_cast<double>(
- test_time.ToDeltaSinceWindowsEpoch().InMicroseconds())));
- clock()->SetNow(test_time);
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(test_time, embargo_start_time);
- // Remove records of dismiss and ignore embargoes and confirm start time
- // reverts to default.
- autoblocker()->RemoveEmbargoAndResetCounts(
- base::BindRepeating(&FilterGoogle));
- embargo_start_time =
- autoblocker()->GetEmbargoStartTime(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(base::Time(), embargo_start_time);
- }
- // Tests the alternating pattern of the block on multiple dismiss behaviour. On
- // N dismissals, the origin to be embargoed for the requested permission and
- // automatically blocked. Each time the embargo is lifted, the site gets another
- // chance to request the permission, but if it is again dismissed it is placed
- // under embargo again and its permission requests blocked.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargoBackoff) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- base::HistogramTester histograms;
- // Record some dismisses.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- // A request with < 3 prior dismisses should not be automatically blocked.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // After the 3rd dismiss subsequent permission requests should be autoblocked.
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Accelerate time forward, check that the embargo status is lifted and the
- // request won't be automatically blocked.
- clock()->Advance(base::Days(8));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Record another dismiss, subsequent requests should be autoblocked again.
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- // Accelerate time again, check embargo is lifted and another permission
- // request is let through.
- clock()->Advance(base::Days(8));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_FALSE(result.has_value());
- // Record another dismiss, subsequent requests should be autoblocked again.
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::GEOLOCATION, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::GEOLOCATION);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- }
- // Tests the alternating pattern of the block on multiple ignores behaviour.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, TestIgnoreEmbargoBackoff) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- base::HistogramTester histograms;
- // Record some ignores.
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- // A request with < 4 prior ignores should not be automatically blocked.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_FALSE(result.has_value());
- // After the 4th ignore subsequent permission requests should be autoblocked.
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result->source);
- // Accelerate time forward, check that the embargo status is lifted and the
- // request won't be automatically blocked.
- clock()->Advance(base::Days(8));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_FALSE(result.has_value());
- // Record another dismiss, subsequent requests should be autoblocked again.
- EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result->source);
- // Accelerate time again, check embargo is lifted and another permission
- // request is let through.
- clock()->Advance(base::Days(8));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_FALSE(result.has_value());
- // Record another dismiss, subsequent requests should be autoblocked again.
- EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::MIDI_SYSEX, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::MIDI_SYSEX);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result->source);
- }
- // Test that quiet ui embargo has a different threshold for ignores.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, TestIgnoreEmbargoUsingQuietUi) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- // Check the default state.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // One quiet ui ignore is not enough to trigger embargo.
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, true));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // Loud ui ignores are counted separately.
- EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // The second quiet ui ignore puts the url under embargo.
- EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, true));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result->source);
- }
- // Test that quiet ui embargo has a different threshold for dismisses.
- TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDismissEmbargoUsingQuietUi) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- // Check the default state.
- absl::optional<PermissionResult> result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // One loud ui dismiss does not trigger embargo.
- EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, false));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_FALSE(result.has_value());
- // One quiet ui dismiss puts the url under embargo.
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::NOTIFICATIONS, true));
- result =
- autoblocker()->GetEmbargoResult(url, ContentSettingsType::NOTIFICATIONS);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- }
- namespace {
- // Checks that embargo on federated identity permission is lifted only after the
- // passed-in |time_delta| has elapsed.
- void CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- PermissionDecisionAutoBlocker* autoblocker,
- base::SimpleTestClock* clock,
- const GURL& url,
- base::TimeDelta time_delta) {
- ASSERT_LT(base::Minutes(1), time_delta);
- clock->Advance(time_delta - base::Minutes(1));
- absl::optional<PermissionResult> result = autoblocker->GetEmbargoResult(
- url, ContentSettingsType::FEDERATED_IDENTITY_API);
- EXPECT_EQ(CONTENT_SETTING_BLOCK, result->content_setting);
- EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result->source);
- clock->Advance(base::Minutes(2));
- result = autoblocker->GetEmbargoResult(
- url, ContentSettingsType::FEDERATED_IDENTITY_API);
- EXPECT_FALSE(result.has_value());
- }
- } // namespace
- TEST_F(PermissionDecisionAutoBlockerUnitTest,
- TestDismissFederatedIdentityApiBackoff) {
- GURL url("https://www.google.com");
- clock()->SetNow(base::Time::Now());
- absl::optional<PermissionResult> result = autoblocker()->GetEmbargoResult(
- url, ContentSettingsType::FEDERATED_IDENTITY_API);
- EXPECT_FALSE(result.has_value());
- // 2 hour embargo for 1st dismissal
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Hours(2));
- // 1 day embargo for 2nd dismissal
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Days(1));
- // 7 day embargo for 3rd dismissal
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Days(7));
- // 28 day embargo for 4th dismissal (and all additional dismissals)
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Days(28));
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Days(28));
- // Return to 2 hour embargo after
- // PermissionDecisionAutoBlocker::RemoveEmbargoAndResetCounts()
- autoblocker()->RemoveEmbargoAndResetCounts(
- url, ContentSettingsType::FEDERATED_IDENTITY_API);
- result = autoblocker()->GetEmbargoResult(
- url, ContentSettingsType::FEDERATED_IDENTITY_API);
- EXPECT_FALSE(result.has_value());
- EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
- url, ContentSettingsType::FEDERATED_IDENTITY_API, false));
- CheckFederatedIdentityApiEmbargoLiftedAfterTimeElapsing(
- autoblocker(), clock(), url, base::Hours(2));
- }
- } // namespace permissions
|