// 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 "chrome/browser/permissions/permission_decision_auto_blocker.h"

#include <map>
#include <memory>

#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/permissions/permission_uma_util.h"
#include "chrome/browser/permissions/permission_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/safe_browsing/db/test_database_manager.h"

namespace {

bool FilterGoogle(const GURL& url) {
  return url == "https://www.google.com/";
}

bool FilterAll(const GURL& url) {
  return true;
}

class MockSafeBrowsingDatabaseManager
    : public safe_browsing::TestSafeBrowsingDatabaseManager {
 public:
  explicit MockSafeBrowsingDatabaseManager(bool perform_callback, bool enabled)
      : perform_callback_(perform_callback), enabled_(enabled) {}

  bool CheckApiBlacklistUrl(
      const GURL& url,
      safe_browsing::SafeBrowsingDatabaseManager::Client* client) override {
    // Return true when able to synchronously determine that the url is safe.
    if (!enabled_) {
      return true;
    }

    if (perform_callback_) {
      safe_browsing::ThreatMetadata metadata;
      const auto& blacklisted_permissions = permissions_blacklist_.find(url);
      if (blacklisted_permissions != permissions_blacklist_.end())
        metadata.api_permissions = blacklisted_permissions->second;
      client->OnCheckApiBlacklistUrlResult(url, metadata);
    }
    return false;
  }

  bool CancelApiCheck(Client* client) override {
    DCHECK(!perform_callback_);
    // Returns true when client check could be stopped.
    return true;
  }

  void BlacklistUrlPermissions(const GURL& url,
                               const std::set<std::string> permissions) {
    permissions_blacklist_[url] = permissions;
  }

  void SetPerformCallback(bool perform_callback) {
    perform_callback_ = perform_callback;
  }

 protected:
  ~MockSafeBrowsingDatabaseManager() override {}

 private:
  bool perform_callback_;
  bool enabled_;
  std::map<GURL, std::set<std::string>> permissions_blacklist_;

  DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
};

}  // namespace

class PermissionDecisionAutoBlockerUnitTest
    : public ChromeRenderViewHostTestHarness {
 protected:
  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();
    autoblocker_ = PermissionDecisionAutoBlocker::GetForProfile(profile());
    feature_list_.InitWithFeatures({features::kBlockPromptsIfDismissedOften,
                                    features::kBlockPromptsIfIgnoredOften,
                                    features::kPermissionsBlacklist},
                                   {});
    last_embargoed_status_ = false;
    std::unique_ptr<base::SimpleTestClock> clock =
        std::make_unique<base::SimpleTestClock>();
    clock_ = clock.get();
    autoblocker_->SetClockForTesting(std::move(clock));
    callback_was_run_ = false;
  }

  void SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(
      scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager,
      int timeout) {
    autoblocker_->SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                                     timeout);
  }

  void CheckSafeBrowsingBlacklist(const GURL& url,
                                  ContentSettingsType permission) {
    base::RunLoop run_loop;
    autoblocker_->CheckSafeBrowsingBlacklist(
        nullptr, url, permission,
        base::Bind(&PermissionDecisionAutoBlockerUnitTest::SetLastEmbargoStatus,
                   base::Unretained(this), run_loop.QuitClosure()));
    run_loop.Run();
  }

  // Manually placing an (origin, permission) pair under embargo for
  // blacklisting. To embargo on dismissals, RecordDismissAndEmbargo can be
  // used.
  void PlaceUnderBlacklistEmbargo(const GURL& url,
                                  ContentSettingsType permission) {
    autoblocker_->PlaceUnderEmbargo(
        url, permission,
        PermissionDecisionAutoBlocker::kPermissionBlacklistEmbargoKey);
  }

  PermissionDecisionAutoBlocker* autoblocker() { return autoblocker_; }

  void SetLastEmbargoStatus(base::Closure quit_closure, bool status) {
    callback_was_run_ = true;
    last_embargoed_status_ = status;
    if (quit_closure) {
      quit_closure.Run();
      quit_closure.Reset();
    }
  }

  bool last_embargoed_status() { return last_embargoed_status_; }

  bool callback_was_run() { return callback_was_run_; }

  base::SimpleTestClock* clock() { return clock_; }

 private:
  PermissionDecisionAutoBlocker* autoblocker_;
  base::test::ScopedFeatureList feature_list_;
  base::SimpleTestClock* clock_;
  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, RemoveEmbargoByUrl) {
  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, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  // Record dismissals for location in |url2|.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // Verify all dismissals recorded above resulted in embargo.
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url1, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
  result = autoblocker()->GetEmbargoResult(url1,
                                           CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
  result =
      autoblocker()->GetEmbargoResult(url2, CONTENT_SETTINGS_TYPE_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()->RemoveEmbargoByUrl(url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  result =
      autoblocker()->GetEmbargoResult(url1, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
  result = autoblocker()->GetEmbargoResult(url1,
                                           CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  // If not under embargo, GetEmbargoResult() returns a setting of ASK.
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  // Verify |url2|'s embargo is still intact as well.
  result =
      autoblocker()->GetEmbargoResult(url2, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
}

// Test that removing embargo from blacklisted permissions also works.
TEST_F(PermissionDecisionAutoBlockerUnitTest,
       RemoveEmbargoByUrlForBlacklistedPermission) {
  GURL url("https://www.example.com");

  // Place under embargo and verify.
  PlaceUnderBlacklistEmbargo(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);

  // Remove embargo and verify.
  autoblocker()->RemoveEmbargoByUrl(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
}

// Test it still only takes 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, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // Verify location is under embargo.
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);

  // Remove embargo and verify this is true.
  autoblocker()->RemoveEmbargoByUrl(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Record another dismissal and verify location is under embargo again.
  autoblocker()->RecordDismissAndEmbargo(url,
                                         CONTENT_SETTINGS_TYPE_GEOLOCATION);
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
}

TEST_F(PermissionDecisionAutoBlockerUnitTest, RemoveCountsByUrl) {
  GURL url1("https://www.google.com");
  GURL url2("https://www.example.com");

  // Record some dismissals.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(2, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(3, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));

  // Record some ignores.
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_EQ(
      1, autoblocker()->GetIgnoreCount(url1, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));
  EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(2, autoblocker()->GetIgnoreCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  autoblocker()->RemoveCountsByUrl(base::Bind(&FilterGoogle));

  // Expect that url1's actions are gone, but url2's remain.
  EXPECT_EQ(0, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(0, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(
      0, autoblocker()->GetIgnoreCount(url1, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));

  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(2, autoblocker()->GetIgnoreCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // Add some more actions.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(1, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));

  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(2, autoblocker()->GetDismissCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url1, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));
  EXPECT_EQ(1, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url2, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_EQ(
      1, autoblocker()->GetIgnoreCount(url2, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));

  // Remove everything and expect that it's all gone.
  autoblocker()->RemoveCountsByUrl(base::Bind(&FilterAll));

  EXPECT_EQ(0, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(0, autoblocker()->GetDismissCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(0, autoblocker()->GetDismissCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
                   url1, CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
  EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
                   url2, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_EQ(0, autoblocker()->GetIgnoreCount(
                   url2, CONTENT_SETTINGS_TYPE_DURABLE_STORAGE));
  EXPECT_EQ(
      0, autoblocker()->GetIgnoreCount(url2, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
}

// Test that an origin that has been blacklisted for a permission is embargoed.
TEST_F(PermissionDecisionAutoBlockerUnitTest, TestUpdateEmbargoBlacklist) {
  GURL url("https://www.google.com");
  base::HistogramTester histograms;

  scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
      new MockSafeBrowsingDatabaseManager(true /* perform_callback */,
                                          true /* enabled */);
  std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
  db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     2000 /* timeout in ms */);

  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_TRUE(callback_was_run());
  EXPECT_TRUE(last_embargoed_status());
  histograms.ExpectUniqueSample(
      "Permissions.AutoBlocker.SafeBrowsingResponse",
      static_cast<int>(SafeBrowsingResponse::BLACKLISTED), 1);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 1);
}

// Test that an origin that is blacklisted for a permission will not be placed
// under embargo for another permission.
TEST_F(PermissionDecisionAutoBlockerUnitTest, TestRequestNotBlacklisted) {
  GURL url("https://www.google.com");
  clock()->SetNow(base::Time::Now());
  base::HistogramTester histograms;

  scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
      new MockSafeBrowsingDatabaseManager(true /* perform_callback */,
                                          true /* enabled */);
  std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
  db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     0 /* timeout in ms */);

  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  EXPECT_FALSE(last_embargoed_status());
  histograms.ExpectUniqueSample(
      "Permissions.AutoBlocker.SafeBrowsingResponse",
      static_cast<int>(SafeBrowsingResponse::NOT_BLACKLISTED), 1);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 1);
}

// Check that we do not apply embargo to the plugins content type, as prompts
// should be triggered only when necessary by Html5ByDefault.
TEST_F(PermissionDecisionAutoBlockerUnitTest,
       PluginsNotEmbargoedByMultipleDismissesOrIgnores) {
  GURL url("https://www.google.com");

  // Check dismisses first.
  autoblocker()->RecordDismissAndEmbargo(url, CONTENT_SETTINGS_TYPE_PLUGINS);
  autoblocker()->RecordDismissAndEmbargo(url, CONTENT_SETTINGS_TYPE_PLUGINS);
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(2,
            autoblocker()->GetDismissCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));

  // The third dismiss would normally embargo, but this shouldn't happen for
  // plugins.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_PLUGINS));
  result = autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(3,
            autoblocker()->GetDismissCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));

  // Extra one for sanity checking.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_PLUGINS));
  result = autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(4,
            autoblocker()->GetDismissCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));

  // Check ignores.
  autoblocker()->RecordIgnoreAndEmbargo(url, CONTENT_SETTINGS_TYPE_PLUGINS);
  autoblocker()->RecordIgnoreAndEmbargo(url, CONTENT_SETTINGS_TYPE_PLUGINS);
  autoblocker()->RecordIgnoreAndEmbargo(url, CONTENT_SETTINGS_TYPE_PLUGINS);
  result = autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(3,
            autoblocker()->GetIgnoreCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));

  // The fourth ignore would normally embargo, but this shouldn't happen for
  // plugins.
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_PLUGINS));
  result = autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(4,
            autoblocker()->GetIgnoreCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));

  // Extra one for sanity checking.
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_PLUGINS));
  result = autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_PLUGINS);

  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
  EXPECT_EQ(5,
            autoblocker()->GetIgnoreCount(url, CONTENT_SETTINGS_TYPE_PLUGINS));
}

// 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.
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Place under embargo and verify.
  PlaceUnderBlacklistEmbargo(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);

  // Check that the origin is not under embargo for a different permission.
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Confirm embargo status during the embargo period.
  clock()->Advance(base::TimeDelta::FromDays(5));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, 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::TimeDelta::FromHours(3 * 24 + 1));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Check embargo is lifted well after the expiry day.
  clock()->Advance(base::TimeDelta::FromDays(1));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Place under embargo again and verify the embargo status.
  PlaceUnderBlacklistEmbargo(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  clock()->Advance(base::TimeDelta::FromDays(1));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);
}

// 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, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // A request with < 3 prior dismisses should not be automatically blocked.
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // After the 3rd dismiss subsequent permission requests should be autoblocked.
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);

  histograms.ExpectTotalCount("Permissions.AutoBlocker.SafeBrowsingResponse",
                              0);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 0);
  // Accelerate time forward, check that the embargo status is lifted and the
  // request won't be automatically blocked.
  clock()->Advance(base::TimeDelta::FromDays(8));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Record another dismiss, subsequent requests should be autoblocked again.
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_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::TimeDelta::FromDays(8));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Record another dismiss, subsequent requests should be autoblocked again.
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
  histograms.ExpectTotalCount("Permissions.AutoBlocker.SafeBrowsingResponse",
                              0);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 0);
}

// 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, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));

  // A request with < 4 prior ignores should not be automatically blocked.
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // After the 4th ignore subsequent permission requests should be autoblocked.
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result.source);

  histograms.ExpectTotalCount("Permissions.AutoBlocker.SafeBrowsingResponse",
                              0);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 0);
  // Accelerate time forward, check that the embargo status is lifted and the
  // request won't be automatically blocked.
  clock()->Advance(base::TimeDelta::FromDays(8));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Record another dismiss, subsequent requests should be autoblocked again.
  EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_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::TimeDelta::FromDays(8));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  // Record another dismiss, subsequent requests should be autoblocked again.
  EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result.source);
  histograms.ExpectTotalCount("Permissions.AutoBlocker.SafeBrowsingResponse",
                              0);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 0);
}

// Test the logic for a combination of blacklisting and dismissal embargo.
TEST_F(PermissionDecisionAutoBlockerUnitTest, TestExpiringOverlappingEmbargo) {
  GURL url("https://www.google.com");
  clock()->SetNow(base::Time::Now());

  // Place under blacklist embargo and check the status.
  PlaceUnderBlacklistEmbargo(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  clock()->Advance(base::TimeDelta::FromDays(5));
  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);

  // Record dismisses to place it under dismissal embargo.
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_TRUE(autoblocker()->RecordDismissAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // Accelerate time to a point where the blacklist embargo should be expired
  // and check that dismissal embargo is still set.
  clock()->Advance(base::TimeDelta::FromDays(3));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);

  // Record an ignore embargo.
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_FALSE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));
  EXPECT_TRUE(autoblocker()->RecordIgnoreAndEmbargo(
      url, CONTENT_SETTINGS_TYPE_GEOLOCATION));

  // Ensure the ignore embargo is still set.
  clock()->Advance(base::TimeDelta::FromDays(5));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::MULTIPLE_IGNORES, result.source);
}

TEST_F(PermissionDecisionAutoBlockerUnitTest, TestSafeBrowsingTimeout) {
  GURL url("https://www.google.com");
  clock()->SetNow(base::Time::Now());
  base::HistogramTester histograms;

  scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
      new MockSafeBrowsingDatabaseManager(false /* perform_callback */,
                                          true /* enabled */);
  std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
  db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     0 /* timeout in ms */);

  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_TRUE(callback_was_run());
  EXPECT_FALSE(last_embargoed_status());

  PermissionResult result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);

  histograms.ExpectUniqueSample("Permissions.AutoBlocker.SafeBrowsingResponse",
                                static_cast<int>(SafeBrowsingResponse::TIMEOUT),
                                1);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 1);
  db_manager->SetPerformCallback(true);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     2000 /* timeout in ms */);

  clock()->Advance(base::TimeDelta::FromDays(1));
  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_TRUE(callback_was_run());
  EXPECT_TRUE(last_embargoed_status());
  histograms.ExpectTotalCount("Permissions.AutoBlocker.SafeBrowsingResponse",
                              2);
  histograms.ExpectTotalCount(
      "Permissions.AutoBlocker.SafeBrowsingResponseTime", 2);
  histograms.ExpectBucketCount(
      "Permissions.AutoBlocker.SafeBrowsingResponse",
      static_cast<int>(SafeBrowsingResponse::BLACKLISTED), 1);
  clock()->Advance(base::TimeDelta::FromDays(1));
  result =
      autoblocker()->GetEmbargoResult(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
  EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);
}

// Test that a blacklisted permission should not be autoblocked if the database
// manager is disabled.
TEST_F(PermissionDecisionAutoBlockerUnitTest, TestDisabledDatabaseManager) {
  GURL url("https://www.google.com");
  scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
      new MockSafeBrowsingDatabaseManager(true /* perform_callback */,
                                          false /* enabled */);
  std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
  db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     2000 /* timeout in ms */);
  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_GEOLOCATION);
  EXPECT_TRUE(callback_was_run());
  EXPECT_FALSE(last_embargoed_status());
}

TEST_F(PermissionDecisionAutoBlockerUnitTest, TestSafeBrowsingResponse) {
  GURL url("https://www.google.com");
  clock()->SetNow(base::Time::Now());
  base::HistogramTester histograms;

  scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
      new MockSafeBrowsingDatabaseManager(true /* perform_callback */,
                                          true /* enabled */);
  std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
  db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
  SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
                                                     0 /* timeout in ms */);

  CheckSafeBrowsingBlacklist(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
  EXPECT_FALSE(last_embargoed_status());
  histograms.ExpectUniqueSample(
      "Permissions.AutoBlocker.SafeBrowsingResponse",
      static_cast<int>(SafeBrowsingResponse::NOT_BLACKLISTED), 1);
}
