// Copyright 2014 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_context_base.h"

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.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_types.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/permissions/permission_request_id.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/permission_uma_util.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/test/mock_permission_prompt_factory.h"
#include "components/permissions/test/test_permissions_client.h"
#include "components/ukm/content/source_url_recorder.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/url_util.h"

namespace permissions {

const char* const kPermissionsKillSwitchFieldStudy =
    PermissionContextBase::kPermissionsKillSwitchFieldStudy;
const char* const kPermissionsKillSwitchBlockedValue =
    PermissionContextBase::kPermissionsKillSwitchBlockedValue;
const char kPermissionsKillSwitchTestGroup[] = "TestGroup";

class TestPermissionContext : public PermissionContextBase {
 public:
  TestPermissionContext(content::BrowserContext* browser_context,
                        const ContentSettingsType content_settings_type)
      : PermissionContextBase(
            browser_context,
            content_settings_type,
            blink::mojom::PermissionsPolicyFeature::kNotFound),
        tab_context_updated_(false) {}

  TestPermissionContext(const TestPermissionContext&) = delete;
  TestPermissionContext& operator=(const TestPermissionContext&) = delete;

  ~TestPermissionContext() override {}

  const std::vector<ContentSetting>& decisions() const { return decisions_; }

  bool tab_context_updated() const { return tab_context_updated_; }

  // Once a decision for the requested permission has been made, run the
  // callback.
  void TrackPermissionDecision(ContentSetting content_setting) {
    decisions_.push_back(content_setting);
    // Null check required here as the quit_closure_ can also be run and reset
    // first from within DecidePermission.
    if (quit_closure_) {
      std::move(quit_closure_).Run();
    }
  }

  ContentSetting GetContentSettingFromMap(const GURL& url_a,
                                          const GURL& url_b) {
    auto* map = PermissionsClient::Get()->GetSettingsMap(browser_context());
    return map->GetContentSetting(url_a.DeprecatedGetOriginAsURL(),
                                  url_b.DeprecatedGetOriginAsURL(),
                                  content_settings_type());
  }

  void RequestPermission(content::WebContents* web_contents,
                         const PermissionRequestID& id,
                         const GURL& requesting_frame,
                         bool user_gesture,
                         BrowserPermissionCallback callback) override {
    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    PermissionContextBase::RequestPermission(web_contents, id, requesting_frame,
                                             true /* user_gesture */,
                                             std::move(callback));
    run_loop.Run();
  }

  void DecidePermission(content::WebContents* web_contents,
                        const PermissionRequestID& id,
                        const GURL& requesting_origin,
                        const GURL& embedding_origin,
                        bool user_gesture,
                        BrowserPermissionCallback callback) override {
    PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
                                            embedding_origin, user_gesture,
                                            std::move(callback));
    if (respond_permission_) {
      std::move(respond_permission_).Run();
    } else {
      // Stop the run loop from spinning indefinitely if no response callback
      // has been set, as is the case with TestParallelRequests.
      std::move(quit_closure_).Run();
    }
  }

  // Set the callback to run if the permission is being responded to in the
  // test. This is left empty where no response is needed, such as in parallel
  // requests, invalid origin, and killswitch.
  void SetRespondPermissionCallback(base::OnceClosure callback) {
    respond_permission_ = std::move(callback);
  }

 protected:
  void UpdateTabContext(const PermissionRequestID& id,
                        const GURL& requesting_origin,
                        bool allowed) override {
    tab_context_updated_ = true;
  }

  bool IsRestrictedToSecureOrigins() const override { return false; }

 private:
  std::vector<ContentSetting> decisions_;
  bool tab_context_updated_;
  base::OnceClosure quit_closure_;
  // Callback for responding to a permission once the request has been completed
  // (valid URL, kill switch disabled)
  base::OnceClosure respond_permission_;
};

class TestKillSwitchPermissionContext : public TestPermissionContext {
 public:
  TestKillSwitchPermissionContext(
      content::BrowserContext* browser_context,
      const ContentSettingsType content_settings_type)
      : TestPermissionContext(browser_context, content_settings_type) {
    ResetFieldTrialList();
  }

  TestKillSwitchPermissionContext(const TestKillSwitchPermissionContext&) =
      delete;
  TestKillSwitchPermissionContext& operator=(
      const TestKillSwitchPermissionContext&) = delete;

  void ResetFieldTrialList() {
    scoped_feature_list_.Reset();
    scoped_feature_list_.Init();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

class TestSecureOriginRestrictedPermissionContext
    : public TestPermissionContext {
 public:
  TestSecureOriginRestrictedPermissionContext(
      content::BrowserContext* browser_context,
      const ContentSettingsType content_settings_type)
      : TestPermissionContext(browser_context, content_settings_type) {}

  TestSecureOriginRestrictedPermissionContext(
      const TestSecureOriginRestrictedPermissionContext&) = delete;
  TestSecureOriginRestrictedPermissionContext& operator=(
      const TestSecureOriginRestrictedPermissionContext&) = delete;

 protected:
  bool IsRestrictedToSecureOrigins() const override { return true; }
};

class TestPermissionsClientBypassExtensionOriginCheck
    : public TestPermissionsClient {
 public:
  bool CanBypassEmbeddingOriginCheck(const GURL& requesting_origin,
                                     const GURL& embedding_origin) override {
    return requesting_origin.SchemeIs("chrome-extension");
  }
};

class PermissionContextBaseTests : public content::RenderViewHostTestHarness {
 public:
  PermissionContextBaseTests(const PermissionContextBaseTests&) = delete;
  PermissionContextBaseTests& operator=(const PermissionContextBaseTests&) =
      delete;

 protected:
  PermissionContextBaseTests() {}
  ~PermissionContextBaseTests() override {}

  // Accept or dismiss the permission prompt.
  void RespondToPermission(TestPermissionContext* context,
                           const PermissionRequestID& id,
                           const GURL& url,
                           ContentSetting response) {
    DCHECK(response == CONTENT_SETTING_ALLOW ||
           response == CONTENT_SETTING_BLOCK ||
           response == CONTENT_SETTING_ASK);
    using AutoResponseType = PermissionRequestManager::AutoResponseType;
    AutoResponseType decision = AutoResponseType::DISMISS;
    if (response == CONTENT_SETTING_ALLOW)
      decision = AutoResponseType::ACCEPT_ALL;
    else if (response == CONTENT_SETTING_BLOCK)
      decision = AutoResponseType::DENY_ALL;
    prompt_factory_->set_response_type(decision);
  }

  void TestAskAndDecide_TestContent(ContentSettingsType content_settings_type,
                                    ContentSetting decision) {
    ukm::InitializeSourceUrlRecorderForWebContents(web_contents());
    ukm::TestAutoSetUkmRecorder ukm_recorder;
    TestPermissionContext permission_context(browser_context(),
                                             content_settings_type);
    GURL url("https://www.google.com");
    SetUpUrl(url);
    base::HistogramTester histograms;

    const PermissionRequestID id(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId());
    permission_context.SetRespondPermissionCallback(base::BindOnce(
        &PermissionContextBaseTests::RespondToPermission,
        base::Unretained(this), &permission_context, id, url, decision));
    permission_context.RequestPermission(
        web_contents(), id, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));
    ASSERT_EQ(1u, permission_context.decisions().size());
    EXPECT_EQ(decision, permission_context.decisions()[0]);
    EXPECT_TRUE(permission_context.tab_context_updated());

    std::string decision_string;
    absl::optional<PermissionAction> action;
    if (decision == CONTENT_SETTING_ALLOW) {
      decision_string = "Accepted";
      action = PermissionAction::GRANTED;
    } else if (decision == CONTENT_SETTING_BLOCK) {
      decision_string = "Denied";
      action = PermissionAction::DENIED;
    } else if (decision == CONTENT_SETTING_ASK) {
      decision_string = "Dismissed";
      action = PermissionAction::DISMISSED;
    }

    if (!decision_string.empty()) {
      histograms.ExpectUniqueSample(
          "Permissions.Prompt." + decision_string + ".PriorDismissCount2." +
              PermissionUtil::GetPermissionString(content_settings_type),
          0, 1);
      histograms.ExpectUniqueSample(
          "Permissions.Prompt." + decision_string + ".PriorIgnoreCount2." +
              PermissionUtil::GetPermissionString(content_settings_type),
          0, 1);
#if BUILDFLAG(IS_ANDROID)
      histograms.ExpectUniqueSample(
          "Permissions.Action.WithDisposition.ModalDialog",
          static_cast<int>(action.value()), 1);
#else
      histograms.ExpectUniqueSample(
          "Permissions.Action.WithDisposition.AnchoredBubble",
          static_cast<int>(action.value()), 1);
#endif
    }

    EXPECT_EQ(decision, permission_context.GetContentSettingFromMap(url, url));

    histograms.ExpectUniqueSample(
        "Permissions.AutoBlocker.EmbargoPromptSuppression",
        static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);
    histograms.ExpectUniqueSample(
        "Permissions.AutoBlocker.EmbargoStatus",
        static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);

    if (action.has_value()) {
      auto entries = ukm_recorder.GetEntriesByName("Permission");
      EXPECT_EQ(1u, entries.size());
      auto* entry = entries.front();
      ukm_recorder.ExpectEntrySourceHasUrl(entry, url);

      size_t num_values = 0;

      EXPECT_NE(ContentSettingTypeToHistogramValue(content_settings_type,
                                                   &num_values),
                -1);

      EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Source"),
                static_cast<int64_t>(PermissionSourceUI::PROMPT));
      EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "PermissionType"),
                static_cast<int64_t>(ContentSettingTypeToHistogramValue(
                    content_settings_type, &num_values)));
      EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Action"),
                static_cast<int64_t>(action.value()));

#if BUILDFLAG(IS_ANDROID)
      EXPECT_EQ(
          *ukm_recorder.GetEntryMetric(entry, "PromptDisposition"),
          static_cast<int64_t>(PermissionPromptDisposition::MODAL_DIALOG));
#else
      EXPECT_EQ(
          *ukm_recorder.GetEntryMetric(entry, "PromptDisposition"),
          static_cast<int64_t>(PermissionPromptDisposition::ANCHORED_BUBBLE));
#endif
    }
  }

  void DismissMultipleTimesAndExpectBlock(
      const GURL& url,
      ContentSettingsType content_settings_type,
      uint32_t iterations) {
    base::HistogramTester histograms;

    // Dismiss |iterations| times. The final dismiss should change the decision
    // from dismiss to block, and hence change the persisted content setting.
    for (uint32_t i = 0; i < iterations; ++i) {
      TestPermissionContext permission_context(browser_context(),
                                               content_settings_type);
      const PermissionRequestID id(
          web_contents()->GetMainFrame()->GetProcess()->GetID(),
          web_contents()->GetMainFrame()->GetRoutingID(),
          PermissionRequestID::RequestLocalId());

      permission_context.SetRespondPermissionCallback(
          base::BindOnce(&PermissionContextBaseTests::RespondToPermission,
                         base::Unretained(this), &permission_context, id, url,
                         CONTENT_SETTING_ASK));

      permission_context.RequestPermission(
          web_contents(), id, url, true /* user_gesture */,
          base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                         base::Unretained(&permission_context)));
      histograms.ExpectTotalCount(
          "Permissions.Prompt.Dismissed.PriorDismissCount2." +
              PermissionUtil::GetPermissionString(content_settings_type),
          i + 1);
      histograms.ExpectBucketCount(
          "Permissions.Prompt.Dismissed.PriorDismissCount2." +
              PermissionUtil::GetPermissionString(content_settings_type),
          i, 1);

      histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
                                  i + 1);

      PermissionResult result = permission_context.GetPermissionStatus(
          nullptr /* render_frame_host */, url, url);

      histograms.ExpectUniqueSample(
          "Permissions.AutoBlocker.EmbargoPromptSuppression",
          static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
      if (i < 2) {
        EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
        EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
        histograms.ExpectUniqueSample(
            "Permissions.AutoBlocker.EmbargoStatus",
            static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
      } else {
        EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
        EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
        histograms.ExpectBucketCount(
            "Permissions.AutoBlocker.EmbargoStatus",
            static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
      }

      ASSERT_EQ(1u, permission_context.decisions().size());
      EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
      EXPECT_TRUE(permission_context.tab_context_updated());
    }

    TestPermissionContext permission_context(browser_context(),
                                             content_settings_type);
    const PermissionRequestID id(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId());

    permission_context.SetRespondPermissionCallback(
        base::BindOnce(&PermissionContextBaseTests::RespondToPermission,
                       base::Unretained(this), &permission_context, id, url,
                       CONTENT_SETTING_ASK));

    permission_context.RequestPermission(
        web_contents(), id, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));

    PermissionResult result = permission_context.GetPermissionStatus(
        nullptr /* render_frame_host */, url, url);
    EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
    EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
    histograms.ExpectBucketCount(
        "Permissions.AutoBlocker.EmbargoPromptSuppression",
        static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
  }

  void TestBlockOnSeveralDismissals_TestContent() {
    GURL url("https://www.google.com");
    SetUpUrl(url);
    base::HistogramTester histograms;

    {
      // Ensure that > 3 dismissals behaves correctly when the
      // BlockPromptsIfDismissedOften feature is off.
      base::test::ScopedFeatureList feature_list;
      feature_list.InitAndDisableFeature(
          features::kBlockPromptsIfDismissedOften);

      for (uint32_t i = 0; i < 4; ++i) {
        TestPermissionContext permission_context(
            browser_context(), ContentSettingsType::GEOLOCATION);

        const PermissionRequestID id(
            web_contents()->GetMainFrame()->GetProcess()->GetID(),
            web_contents()->GetMainFrame()->GetRoutingID(),
            PermissionRequestID::RequestLocalId(i + 1));

        permission_context.SetRespondPermissionCallback(
            base::BindOnce(&PermissionContextBaseTests::RespondToPermission,
                           base::Unretained(this), &permission_context, id, url,
                           CONTENT_SETTING_ASK));
        permission_context.RequestPermission(
            web_contents(), id, url, true /* user_gesture */,
            base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                           base::Unretained(&permission_context)));
        histograms.ExpectTotalCount(
            "Permissions.Prompt.Dismissed.PriorDismissCount2.Geolocation",
            i + 1);
        histograms.ExpectBucketCount(
            "Permissions.Prompt.Dismissed.PriorDismissCount2.Geolocation", i,
            1);
        histograms.ExpectUniqueSample(
            "Permissions.AutoBlocker.EmbargoPromptSuppression",
            static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
        histograms.ExpectUniqueSample(
            "Permissions.AutoBlocker.EmbargoStatus",
            static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);

        ASSERT_EQ(1u, permission_context.decisions().size());
        EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
        EXPECT_TRUE(permission_context.tab_context_updated());
        EXPECT_EQ(CONTENT_SETTING_ASK,
                  permission_context.GetContentSettingFromMap(url, url));
      }

      // Flush the dismissal counts.
      auto* map = PermissionsClient::Get()->GetSettingsMap(browser_context());
      map->ClearSettingsForOneType(
          ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA);
    }

    EXPECT_TRUE(
        base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));

    // Sanity check independence per permission type by checking two of them.
    DismissMultipleTimesAndExpectBlock(url, ContentSettingsType::GEOLOCATION,
                                       3);
    DismissMultipleTimesAndExpectBlock(url, ContentSettingsType::NOTIFICATIONS,
                                       3);
  }

  void TestVariationBlockOnSeveralDismissals_TestContent() {
    GURL url("https://www.google.com");
    SetUpUrl(url);
    base::HistogramTester histograms;

    std::map<std::string, std::string> params;
    params
        [PermissionDecisionAutoBlocker::GetPromptDismissCountKeyForTesting()] =
            "5";
    base::test::ScopedFeatureList scoped_feature_list;
    scoped_feature_list.InitAndEnableFeatureWithParameters(
        features::kBlockPromptsIfDismissedOften, params);

    std::map<std::string, std::string> actual_params;
    EXPECT_TRUE(base::GetFieldTrialParamsByFeature(
        features::kBlockPromptsIfDismissedOften, &actual_params));
    EXPECT_EQ(params, actual_params);

    EXPECT_TRUE(base::GetFieldTrialParamsByFeature(
        features::kBlockPromptsIfDismissedOften, &actual_params));
    EXPECT_EQ(params, actual_params);

    for (uint32_t i = 0; i < 5; ++i) {
      TestPermissionContext permission_context(browser_context(),
                                               ContentSettingsType::MIDI_SYSEX);

      const PermissionRequestID id(
          web_contents()->GetMainFrame()->GetProcess()->GetID(),
          web_contents()->GetMainFrame()->GetRoutingID(),
          PermissionRequestID::RequestLocalId(i + 1));
      permission_context.SetRespondPermissionCallback(
          base::BindOnce(&PermissionContextBaseTests::RespondToPermission,
                         base::Unretained(this), &permission_context, id, url,
                         CONTENT_SETTING_ASK));
      permission_context.RequestPermission(
          web_contents(), id, url, true /* user_gesture */,
          base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                         base::Unretained(&permission_context)));

      EXPECT_EQ(1u, permission_context.decisions().size());
      ASSERT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
      EXPECT_TRUE(permission_context.tab_context_updated());
      PermissionResult result = permission_context.GetPermissionStatus(
          nullptr /* render_frame_host */, url, url);

      histograms.ExpectTotalCount(
          "Permissions.Prompt.Dismissed.PriorDismissCount2.MidiSysEx", i + 1);
      histograms.ExpectBucketCount(
          "Permissions.Prompt.Dismissed.PriorDismissCount2.MidiSysEx", i, 1);
      histograms.ExpectUniqueSample(
          "Permissions.AutoBlocker.EmbargoPromptSuppression",
          static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
      histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
                                  i + 1);
      if (i < 4) {
        EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
        EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
        histograms.ExpectUniqueSample(
            "Permissions.AutoBlocker.EmbargoStatus",
            static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
      } else {
        EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
        EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
        histograms.ExpectBucketCount(
            "Permissions.AutoBlocker.EmbargoStatus",
            static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
      }
    }

    // Ensure that we finish in the block state.
    TestPermissionContext permission_context(browser_context(),
                                             ContentSettingsType::MIDI_SYSEX);
    PermissionResult result = permission_context.GetPermissionStatus(
        nullptr /* render_frame_host */, url, url);
    EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
    EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
  }

  void TestRequestPermissionInvalidUrl(
      ContentSettingsType content_settings_type) {
    base::HistogramTester histograms;
    TestPermissionContext permission_context(browser_context(),
                                             content_settings_type);
    GURL url;
    ASSERT_FALSE(url.is_valid());
    controller().LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_TYPED,
                         std::string());

    const PermissionRequestID id(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId());
    permission_context.RequestPermission(
        web_contents(), id, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));

    ASSERT_EQ(1u, permission_context.decisions().size());
    EXPECT_EQ(CONTENT_SETTING_BLOCK, permission_context.decisions()[0]);
    EXPECT_TRUE(permission_context.tab_context_updated());
    EXPECT_EQ(CONTENT_SETTING_ASK,
              permission_context.GetContentSettingFromMap(url, url));
    histograms.ExpectTotalCount(
        "Permissions.AutoBlocker.EmbargoPromptSuppression", 0);
  }

  void TestGrantAndRevoke_TestContent(ContentSettingsType content_settings_type,
                                      ContentSetting expected_default) {
    TestPermissionContext permission_context(browser_context(),
                                             content_settings_type);
    GURL url("https://www.google.com");
    SetUpUrl(url);

    const PermissionRequestID id(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId());
    permission_context.SetRespondPermissionCallback(
        base::BindOnce(&PermissionContextBaseTests::RespondToPermission,
                       base::Unretained(this), &permission_context, id, url,
                       CONTENT_SETTING_ALLOW));

    permission_context.RequestPermission(
        web_contents(), id, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));

    ASSERT_EQ(1u, permission_context.decisions().size());
    EXPECT_EQ(CONTENT_SETTING_ALLOW, permission_context.decisions()[0]);
    EXPECT_TRUE(permission_context.tab_context_updated());
    EXPECT_EQ(CONTENT_SETTING_ALLOW,
              permission_context.GetContentSettingFromMap(url, url));

    // Try to reset permission.
    permission_context.ResetPermission(url.DeprecatedGetOriginAsURL(),
                                       url.DeprecatedGetOriginAsURL());
    ContentSetting setting_after_reset =
        permission_context.GetContentSettingFromMap(url, url);
    ContentSetting default_setting =
        PermissionsClient::Get()
            ->GetSettingsMap(browser_context())
            ->GetDefaultContentSetting(content_settings_type, nullptr);
    EXPECT_EQ(default_setting, setting_after_reset);
  }

  void TestGlobalPermissionsKillSwitch(
      ContentSettingsType content_settings_type) {
    TestKillSwitchPermissionContext permission_context(browser_context(),
                                                       content_settings_type);
    permission_context.ResetFieldTrialList();

    EXPECT_FALSE(permission_context.IsPermissionKillSwitchOn());
    std::map<std::string, std::string> params;
    params[PermissionUtil::GetPermissionString(content_settings_type)] =
        kPermissionsKillSwitchBlockedValue;
    base::AssociateFieldTrialParams(kPermissionsKillSwitchFieldStudy,
                                    kPermissionsKillSwitchTestGroup, params);
    base::FieldTrialList::CreateFieldTrial(kPermissionsKillSwitchFieldStudy,
                                           kPermissionsKillSwitchTestGroup);
    EXPECT_TRUE(permission_context.IsPermissionKillSwitchOn());
  }

  void TestSecureOriginRestrictedPermissionContextCheck(
      const std::string& requesting_url_spec,
      const std::string& embedding_url_spec,
      bool expect_allowed) {
    GURL requesting_origin(requesting_url_spec);
    GURL embedding_origin(embedding_url_spec);
    TestSecureOriginRestrictedPermissionContext permission_context(
        browser_context(), ContentSettingsType::GEOLOCATION);
    bool result = permission_context.IsPermissionAvailableToOrigins(
        requesting_origin, embedding_origin);
    EXPECT_EQ(expect_allowed, result)
        << "test case (requesting, embedding): (" << requesting_url_spec << ", "
        << embedding_url_spec << ") with secure-origin requirement"
        << " on";

    // With no secure-origin limitation, this check should always return pass.
    TestPermissionContext new_context(browser_context(),
                                      ContentSettingsType::GEOLOCATION);
    result = new_context.IsPermissionAvailableToOrigins(requesting_origin,
                                                        embedding_origin);
    EXPECT_EQ(true, result)
        << "test case (requesting, embedding): (" << requesting_url_spec << ", "
        << embedding_url_spec << ") with secure-origin requirement"
        << " off";
  }

  // Don't call this more than once in the same test, as it persists data to
  // HostContentSettingsMap.
  void TestParallelRequests(ContentSetting response) {
    TestPermissionContext permission_context(browser_context(),
                                             ContentSettingsType::GEOLOCATION);
    GURL url("http://www.google.com");
    SetUpUrl(url);

    const PermissionRequestID id1(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId(1));
    const PermissionRequestID id2(
        web_contents()->GetMainFrame()->GetProcess()->GetID(),
        web_contents()->GetMainFrame()->GetRoutingID(),
        PermissionRequestID::RequestLocalId(2));

    // Request a permission without setting the callback to DecidePermission.
    permission_context.RequestPermission(
        web_contents(), id1, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));

    EXPECT_EQ(0u, permission_context.decisions().size());

    // Set the callback, and make a second permission request.
    permission_context.SetRespondPermissionCallback(base::BindOnce(
        &PermissionContextBaseTests::RespondToPermission,
        base::Unretained(this), &permission_context, id1, url, response));
    permission_context.RequestPermission(
        web_contents(), id2, url, true /* user_gesture */,
        base::BindOnce(&TestPermissionContext::TrackPermissionDecision,
                       base::Unretained(&permission_context)));

    ASSERT_EQ(2u, permission_context.decisions().size());
    EXPECT_EQ(response, permission_context.decisions()[0]);
    EXPECT_EQ(response, permission_context.decisions()[1]);
    EXPECT_TRUE(permission_context.tab_context_updated());

    EXPECT_EQ(response, permission_context.GetContentSettingFromMap(url, url));
  }

  void TestVirtualURL(const GURL& loaded_url,
                      const GURL& virtual_url,
                      const ContentSetting want_response,
                      const PermissionStatusSource& want_source) {
    TestPermissionContext permission_context(browser_context(),
                                             ContentSettingsType::GEOLOCATION);

    NavigateAndCommit(loaded_url);
    web_contents()->GetController().GetVisibleEntry()->SetVirtualURL(
        virtual_url);

    PermissionResult result = permission_context.GetPermissionStatus(
        web_contents()->GetMainFrame(), virtual_url, virtual_url);
    EXPECT_EQ(result.content_setting, want_response);
    EXPECT_EQ(result.source, want_source);
  }

  void SetUpUrl(const GURL& url) {
    NavigateAndCommit(url);
    prompt_factory_->DocumentOnLoadCompletedInPrimaryMainFrame();
  }

 private:
  // content::RenderViewHostTestHarness:
  void SetUp() override {
    content::RenderViewHostTestHarness::SetUp();
    PermissionRequestManager::CreateForWebContents(web_contents());
    PermissionRequestManager* manager =
        PermissionRequestManager::FromWebContents(web_contents());
    manager->set_enabled_app_level_notification_permission_for_testing(true);
    prompt_factory_ = std::make_unique<MockPermissionPromptFactory>(manager);
  }

  void TearDown() override {
    prompt_factory_.reset();
    content::RenderViewHostTestHarness::TearDown();
  }

  std::unique_ptr<MockPermissionPromptFactory> prompt_factory_;
  TestPermissionsClientBypassExtensionOriginCheck client_;
};

// Simulates clicking Accept. The permission should be granted and
// saved for future use.
TEST_F(PermissionContextBaseTests, TestAskAndGrant) {
  TestAskAndDecide_TestContent(ContentSettingsType::NOTIFICATIONS,
                               CONTENT_SETTING_ALLOW);
}

// Simulates clicking Block. The permission should be denied and
// saved for future use.
TEST_F(PermissionContextBaseTests, TestAskAndBlock) {
  TestAskAndDecide_TestContent(ContentSettingsType::GEOLOCATION,
                               CONTENT_SETTING_BLOCK);
}

// Simulates clicking Dismiss (X) in the prompt.
// The permission should be denied but not saved for future use.
TEST_F(PermissionContextBaseTests, TestAskAndDismiss) {
  TestAskAndDecide_TestContent(ContentSettingsType::MIDI_SYSEX,
                               CONTENT_SETTING_ASK);
}

// Simulates clicking Dismiss (X) in the prompt with the block on too
// many dismissals feature active. The permission should be blocked after
// several dismissals.
TEST_F(PermissionContextBaseTests, TestDismissUntilBlocked) {
  TestBlockOnSeveralDismissals_TestContent();
}

// Test setting a custom number of dismissals before block via variations.
TEST_F(PermissionContextBaseTests, TestDismissVariations) {
  TestVariationBlockOnSeveralDismissals_TestContent();
}

// Simulates non-valid requesting URL.
// The permission should be denied but not saved for future use.
TEST_F(PermissionContextBaseTests, TestNonValidRequestingUrl) {
  TestRequestPermissionInvalidUrl(ContentSettingsType::GEOLOCATION);
  TestRequestPermissionInvalidUrl(ContentSettingsType::NOTIFICATIONS);
  TestRequestPermissionInvalidUrl(ContentSettingsType::MIDI_SYSEX);
}

// Simulates granting and revoking of permissions.
TEST_F(PermissionContextBaseTests, TestGrantAndRevoke) {
  TestGrantAndRevoke_TestContent(ContentSettingsType::GEOLOCATION,
                                 CONTENT_SETTING_ASK);
  TestGrantAndRevoke_TestContent(ContentSettingsType::MIDI_SYSEX,
                                 CONTENT_SETTING_ASK);
#if BUILDFLAG(IS_ANDROID)
  TestGrantAndRevoke_TestContent(
      ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, CONTENT_SETTING_ASK);
  // TODO(timvolodine): currently no test for
  // ContentSettingsType::NOTIFICATIONS because notification permissions work
  // differently with infobars as compared to bubbles (crbug.com/453784).
#else
  TestGrantAndRevoke_TestContent(ContentSettingsType::NOTIFICATIONS,
                                 CONTENT_SETTING_ASK);
#endif
}

// Tests the global kill switch by enabling/disabling the Field Trials.
TEST_F(PermissionContextBaseTests, TestGlobalKillSwitch) {
  TestGlobalPermissionsKillSwitch(ContentSettingsType::GEOLOCATION);
  TestGlobalPermissionsKillSwitch(ContentSettingsType::NOTIFICATIONS);
  TestGlobalPermissionsKillSwitch(ContentSettingsType::MIDI_SYSEX);
  TestGlobalPermissionsKillSwitch(ContentSettingsType::DURABLE_STORAGE);
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH)
  TestGlobalPermissionsKillSwitch(
      ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER);
#endif
  TestGlobalPermissionsKillSwitch(ContentSettingsType::MEDIASTREAM_MIC);
  TestGlobalPermissionsKillSwitch(ContentSettingsType::MEDIASTREAM_CAMERA);
}

// Tests that secure origins are examined if switch is on, or ignored if off.
TEST_F(PermissionContextBaseTests,
       TestSecureOriginRestrictedPermissionContextSwitch) {
  url::ScopedSchemeRegistryForTests scoped_registry;
  url::AddSecureScheme("chrome-extension");
  struct {
    std::string requesting_url_spec;
    std::string embedding_url_spec;
    bool expect_permission_allowed;
  } kTestCases[] = {
      // Secure-origins that should be allowed.
      {"https://google.com", "https://foo.com",
       /*expect_allowed=*/true},
      {"https://www.bar.com", "https://foo.com",
       /*expect_allowed=*/true},
      {"https://localhost", "http://localhost",
       /*expect_allowed=*/true},

      {"http://localhost", "https://google.com",
       /*expect_allowed=*/true},
      {"https://google.com", "http://localhost",
       /*expect_allowed=*/true},
      {"https://foo.com", "file://some-file",
       /*expect_allowed=*/true},
      {"file://some-file", "https://foo.com",
       /*expect_allowed=*/true},
      {"https://foo.com", "about:blank",
       /*expect_allowed=*/true},
      {"about:blank", "https://foo.com",
       /*expect_allowed=*/true},

      // Extensions are exempt from checking the embedder chain.
      {"chrome-extension://some-extension", "http://not-secure.com",
       /*expect_allowed=*/true},

      // Insecure-origins that should be blocked.
      {"http://foo.com", "file://some-file",
       /*expect_allowed=*/false},
      {"fake://foo.com", "about:blank",
       /*expect_allowed=*/false},
      {"http://localhost", "http://foo.com",
       /*expect_allowed=*/false},
      {"http://localhost", "foo.com",
       /*expect_allowed=*/false},
      {"http://bar.com", "https://foo.com",
       /*expect_permission_allowed=*/false},
      {"https://foo.com", "http://bar.com",
       /*expect_permission_allowed=*/false},
      {"http://localhost", "http://foo.com",
       /*expect_permission_allowed=*/false},
      {"http://foo.com", "http://localhost",
       /*expect_permission_allowed=*/false},
      {"bar.com", "https://foo.com", /*expect_permission_allowed=*/false},
      {"https://foo.com", "bar.com", /*expect_permission_allowed=*/false}};
  for (const auto& test_case : kTestCases) {
    TestSecureOriginRestrictedPermissionContextCheck(
        test_case.requesting_url_spec, test_case.embedding_url_spec,
        test_case.expect_permission_allowed);
  }
}

TEST_F(PermissionContextBaseTests, TestParallelRequestsAllowed) {
  TestParallelRequests(CONTENT_SETTING_ALLOW);
}

TEST_F(PermissionContextBaseTests, TestParallelRequestsBlocked) {
  TestParallelRequests(CONTENT_SETTING_BLOCK);
}

TEST_F(PermissionContextBaseTests, TestParallelRequestsDismissed) {
  TestParallelRequests(CONTENT_SETTING_ASK);
}

TEST_F(PermissionContextBaseTests, TestVirtualURLDifferentOrigin) {
  TestVirtualURL(GURL("http://www.google.com"), GURL("http://foo.com"),
                 CONTENT_SETTING_BLOCK,
                 PermissionStatusSource::VIRTUAL_URL_DIFFERENT_ORIGIN);
}

TEST_F(PermissionContextBaseTests, TestVirtualURLNotHTTP) {
  TestVirtualURL(GURL("chrome://foo"), GURL("chrome://newtab"),
                 CONTENT_SETTING_ASK, PermissionStatusSource::UNSPECIFIED);
}

TEST_F(PermissionContextBaseTests, TestVirtualURLSameOrigin) {
  TestVirtualURL(GURL("http://www.google.com"),
                 GURL("http://www.google.com/foo"), CONTENT_SETTING_ASK,
                 PermissionStatusSource::UNSPECIFIED);
}

}  // namespace permissions
