// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/permissions/permission_manager.h"

#include <memory>

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.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/content_settings/core/common/features.h"
#include "components/permissions/content_setting_permission_context_base.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/test/mock_permission_prompt_factory.h"
#include "components/permissions/test/permission_test_util.h"
#include "components/permissions/test/test_permissions_client.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/permission_descriptor_util.h"
#include "content/public/browser/permission_request_description.h"
#include "content/public/browser/permission_result.h"
#include "content/public/common/content_client.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_renderer_host.h"
#include "services/network/public/cpp/permissions_policy/origin_with_possible_wildcards.h"
#include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h"
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "url/origin.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/test/metrics/histogram_tester.h"
#include "ui/android/display_android_manager.h"
#endif  // IS_ANDROID

using blink::PermissionType;
using network::mojom::PermissionsPolicyFeature;

namespace permissions {
namespace {

#if BUILDFLAG(IS_ANDROID)
constexpr char kWindowManagementHistogramName[] =
    "Permissions.WindowManagementApi.Android.Allowed";
#endif  // IS_ANDROID

class ScopedPartitionedOriginBrowserClient
    : public content::ContentBrowserClient {
 public:
  explicit ScopedPartitionedOriginBrowserClient(const GURL& app_origin)
      : app_origin_(url::Origin::Create(app_origin)) {
    old_client_ = content::SetBrowserClientForTesting(this);
  }

  ~ScopedPartitionedOriginBrowserClient() override {
    content::SetBrowserClientForTesting(old_client_);
  }

  content::StoragePartitionConfig GetStoragePartitionConfigForSite(
      content::BrowserContext* browser_context,
      const GURL& site) override {
    if (url::Origin::Create(site) == app_origin_) {
      return content::StoragePartitionConfig::Create(
          browser_context, "test_partition", /*partition_name=*/std::string(),
          /*in_memory=*/false);
    }
    return content::StoragePartitionConfig::CreateDefault(browser_context);
  }

 private:
  url::Origin app_origin_;
  raw_ptr<content::ContentBrowserClient> old_client_;
};

}  // namespace

class PermissionManagerTest : public content::RenderViewHostTestHarness {
 public:
  void OnPermissionChange(content::PermissionResult result) {
    if (!quit_closure_.is_null()) {
      std::move(quit_closure_).Run();
    }
    callback_called_ = true;
    callback_count_++;
    callback_result_ = result.status;
  }

 protected:
  PermissionManagerTest()
      : url_("https://example.com"), other_url_("https://foo.com") {}

  PermissionManager* GetPermissionManager() {
    return static_cast<PermissionManager*>(
        browser_context_->GetPermissionControllerDelegate());
  }

  HostContentSettingsMap* GetHostContentSettingsMap() {
    return PermissionsClient::Get()->GetSettingsMap(browser_context_.get());
  }

  void CheckPermissionStatus(PermissionType type,
                             PermissionStatus expected,
                             bool should_include_device_status = false) {
    EXPECT_EQ(expected,
              GetPermissionManager()
                  ->GetPermissionStatusInternal(
                      content::PermissionDescriptorUtil::
                          CreatePermissionDescriptorForPermissionType(type),
                      /*render_process_host=*/nullptr,
                      /*render_frame_host=*/nullptr, url_, url_,
                      should_include_device_status)
                  .status);
  }

  void CheckPermissionResult(
      PermissionType type,
      PermissionStatus expected_status,
      content::PermissionStatusSource expected_status_source) {
    content::PermissionResult result =
        GetPermissionManager()->GetPermissionResultForOriginWithoutContext(
            content::PermissionDescriptorUtil::
                CreatePermissionDescriptorForPermissionType(type),
            url::Origin::Create(url_), url::Origin::Create(url_));
    EXPECT_EQ(expected_status, result.status);
    EXPECT_EQ(expected_status_source, result.source);
  }

  void SetPermission(PermissionType type, PermissionStatus value) {
    SetPermission(url_, url_, type, value);
  }

  void SetPermission(const GURL& origin,
                     PermissionType type,
                     PermissionStatus value) {
    SetPermission(origin, origin, type, value);
  }

  void SetPermission(const GURL& requesting_origin,
                     const GURL& embedding_origin,
                     PermissionType type,
                     PermissionStatus value) {
    GetHostContentSettingsMap()->SetContentSettingDefaultScope(
        requesting_origin, embedding_origin,
        permissions::PermissionUtil::PermissionTypeToContentSettingsType(type),
        permissions::PermissionUtil::PermissionStatusToContentSetting(value));
  }

  void RequestPermissionFromCurrentDocument(PermissionType type,
                                            content::RenderFrameHost* rfh) {
    base::RunLoop loop;
    quit_closure_ = loop.QuitClosure();
    GetPermissionManager()->RequestPermissionsFromCurrentDocument(
        rfh,
        std::move(content::PermissionRequestDescription(
            content::PermissionDescriptorUtil::
                CreatePermissionDescriptorForPermissionType(type),
            /*user_gesture=*/true, rfh->GetLastCommittedOrigin().GetURL())),
        base::BindOnce(
            [](base::OnceCallback<void(content::PermissionResult)> callback,
               const std::vector<content::PermissionResult>& result) {
              DCHECK_EQ(result.size(), 1U);
              std::move(callback).Run(result[0]);
            },
            base::BindOnce(&PermissionManagerTest::OnPermissionChange,
                           base::Unretained(this))));
    loop.Run();
  }

  void RequestPermissionFromCurrentDocumentNonBlocking(
      PermissionType type,
      content::RenderFrameHost* rfh) {
    GetPermissionManager()->RequestPermissionsFromCurrentDocument(
        rfh,
        content::PermissionRequestDescription(
            content::PermissionDescriptorUtil::
                CreatePermissionDescriptorForPermissionType(type),
            /*user_gesture=*/true, rfh->GetLastCommittedOrigin().GetURL()),
        base::BindOnce(
            [](base::OnceCallback<void(content::PermissionResult)> callback,
               const std::vector<content::PermissionResult>& result) {
              DCHECK_EQ(result.size(), 1U);
              std::move(callback).Run(result[0]);
            },
            base::BindOnce(&PermissionManagerTest::OnPermissionChange,
                           base::Unretained(this))));
  }

  PermissionStatus GetPermissionStatusForCurrentDocument(
      PermissionType permission,
      content::RenderFrameHost* render_frame_host) {
    return GetPermissionManager()
        ->GetPermissionResultForCurrentDocument(
            content::PermissionDescriptorUtil::
                CreatePermissionDescriptorForPermissionType(permission),
            render_frame_host, /*should_include_device_status*/ false)
        .status;
  }

  content::PermissionResult GetPermissionResultForCurrentDocument(
      PermissionType permission,
      content::RenderFrameHost* render_frame_host) {
    return GetPermissionManager()->GetPermissionResultForCurrentDocument(
        content::PermissionDescriptorUtil::
            CreatePermissionDescriptorForPermissionType(permission),
        render_frame_host, /*should_include_device_status*/ false);
  }

  PermissionStatus GetPermissionStatusForWorker(
      PermissionType permission,
      content::RenderProcessHost* render_process_host,
      const GURL& worker_origin) {
    return GetPermissionManager()
        ->GetPermissionResultForWorker(
            content::PermissionDescriptorUtil::
                CreatePermissionDescriptorForPermissionType(permission),
            render_process_host, worker_origin)
        .status;
  }

  bool IsPermissionOverridable(PermissionType permission,
                               const std::optional<url::Origin>& origin) {
    return GetPermissionManager()->IsPermissionOverridable(permission, origin,
                                                           origin);
  }

  void ResetPermission(PermissionType permission,
                       const GURL& requesting_origin,
                       const GURL& embedding_origin) {
    GetPermissionManager()->ResetPermission(permission, requesting_origin,
                                            embedding_origin);
  }

  const GURL& url() const { return url_; }

  const GURL& other_url() const { return other_url_; }

  bool callback_called() const { return callback_called_; }

  int callback_count() const { return callback_count_; }

  PermissionStatus callback_result() const { return callback_result_; }

  content::TestBrowserContext* browser_context() const {
    return browser_context_.get();
  }

  void Reset() {
    callback_called_ = false;
    callback_count_ = 0;
    callback_result_ = PermissionStatus::ASK;
  }

  bool PendingRequestsEmpty() {
    return GetPermissionManager()->pending_requests_.IsEmpty();
  }

  // The header policy should only be set once on page load, so we refresh the
  // page to simulate that.
  void RefreshPageAndSetHeaderPolicy(content::RenderFrameHost** rfh,
                                     PermissionsPolicyFeature feature,
                                     const std::vector<std::string>& origins) {
    content::RenderFrameHost* current = *rfh;
    auto navigation = content::NavigationSimulator::CreateRendererInitiated(
        current->GetLastCommittedURL(), current);
    std::vector<network::OriginWithPossibleWildcards> parsed_origins;
    for (const std::string& origin : origins)
      parsed_origins.emplace_back(
          *network::OriginWithPossibleWildcards::FromOrigin(
              url::Origin::Create(GURL(origin))));
    navigation->SetPermissionsPolicyHeader(
        {{feature, parsed_origins, /*self_if_matches=*/std::nullopt,
          /*matches_all_origins=*/false,
          /*matches_opaque_src=*/false}});
    navigation->Commit();
    *rfh = navigation->GetFinalRenderFrameHost();
  }

  content::RenderFrameHost* AddChildRFH(
      content::RenderFrameHost* parent,
      const GURL& origin,
      PermissionsPolicyFeature feature = PermissionsPolicyFeature::kNotFound) {
    network::ParsedPermissionsPolicy frame_policy = {};
    if (feature != PermissionsPolicyFeature::kNotFound) {
      frame_policy.emplace_back(
          feature,
          std::vector{*network::OriginWithPossibleWildcards::FromOrigin(
              url::Origin::Create(origin))},
          /*self_if_matches=*/std::nullopt,
          /*matches_all_origins=*/false,
          /*matches_opaque_src=*/false);
    }
    content::RenderFrameHost* result =
        content::RenderFrameHostTester::For(parent)->AppendChildWithPolicy(
            "", frame_policy);
    content::RenderFrameHostTester::For(result)
        ->InitializeRenderFrameIfNeeded();
    SimulateNavigation(&result, origin);
    return result;
  }

  TestPermissionsClient& permissions_client() { return client_; }

 private:
  void SetUp() override {
    RenderViewHostTestHarness::SetUp();
    browser_context_ = std::make_unique<content::TestBrowserContext>();
    browser_context_->SetPermissionControllerDelegate(
        permissions::GetPermissionControllerDelegate(browser_context_.get()));
    NavigateAndCommit(url());
  }

  void TearDown() override {
    GetPermissionManager()->Shutdown();
    browser_context_ = nullptr;
    RenderViewHostTestHarness::TearDown();
  }

  void SimulateNavigation(content::RenderFrameHost** rfh, const GURL& url) {
    auto navigation_simulator =
        content::NavigationSimulator::CreateRendererInitiated(url, *rfh);
    navigation_simulator->Commit();
    *rfh = navigation_simulator->GetFinalRenderFrameHost();
  }

  const GURL url_;
  const GURL other_url_;
  bool callback_called_ = false;
  int callback_count_ = 0;
  PermissionStatus callback_result_ = PermissionStatus::ASK;
  base::OnceClosure quit_closure_;
  std::unique_ptr<content::TestBrowserContext> browser_context_;
  TestPermissionsClient client_;
};

TEST_F(PermissionManagerTest, GetPermissionStatusDefault) {
  CheckPermissionStatus(PermissionType::MIDI_SYSEX, PermissionStatus::ASK);
  CheckPermissionStatus(PermissionType::NOTIFICATIONS, PermissionStatus::ASK);
  CheckPermissionStatus(PermissionType::GEOLOCATION, PermissionStatus::ASK);
#if BUILDFLAG(IS_ANDROID)
  CheckPermissionStatus(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                        PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::DENIED);
#else
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::ASK);
#endif
}

TEST_F(PermissionManagerTest, GetPermissionStatusAfterSet) {
  SetPermission(PermissionType::GEOLOCATION, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::GEOLOCATION, PermissionStatus::GRANTED);

  SetPermission(PermissionType::NOTIFICATIONS, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::NOTIFICATIONS,
                        PermissionStatus::GRANTED);

  SetPermission(PermissionType::MIDI_SYSEX, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::MIDI_SYSEX, PermissionStatus::GRANTED);

#if BUILDFLAG(IS_ANDROID)
  SetPermission(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                        PermissionStatus::GRANTED);

  SetPermission(PermissionType::WINDOW_MANAGEMENT, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::DENIED);
#else
  SetPermission(PermissionType::WINDOW_MANAGEMENT, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::GRANTED);
#endif
}

#if BUILDFLAG(IS_ANDROID)
TEST_F(PermissionManagerTest, AndroidWindowManagementPermissionDenied) {
  SetPermission(PermissionType::WINDOW_MANAGEMENT, PermissionStatus::GRANTED);

  // Feature flag and Display Topology are disabled.
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::DENIED);

  ui::DisplayAndroidManager::SetIsDisplayTopologyAvailableForTesting(true);

  // Display Topology is enabled, but Feature flag is disabled.
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::DENIED);

  // Enable kAndroidWindowManagementWebApi flag.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      permissions::features::kAndroidWindowManagementWebApi, true);
  ui::DisplayAndroidManager::SetIsDisplayTopologyAvailableForTesting(false);

  // Feature flag is enabled, but Display Topology is disabled.
  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::DENIED);
}

TEST_F(PermissionManagerTest, AndroidWindowManagementPermission) {
  // Enable kAndroidWindowManagementWebApi flag.
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitWithFeatureState(
      permissions::features::kAndroidWindowManagementWebApi, true);

  // Set display topology availability
  ui::DisplayAndroidManager::SetIsDisplayTopologyAvailableForTesting(true);

  CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                        PermissionStatus::ASK);

  {
    base::HistogramTester histogram_tester;

    SetPermission(PermissionType::WINDOW_MANAGEMENT, PermissionStatus::GRANTED);
    CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                          PermissionStatus::GRANTED);

    histogram_tester.ExpectUniqueSample(kWindowManagementHistogramName, true,
                                        1);
  }

  {
    base::HistogramTester histogram_tester;

    SetPermission(PermissionType::WINDOW_MANAGEMENT, PermissionStatus::DENIED);
    CheckPermissionStatus(PermissionType::WINDOW_MANAGEMENT,
                          PermissionStatus::DENIED);

    histogram_tester.ExpectUniqueSample(kWindowManagementHistogramName, false,
                                        1);
  }
}
#endif

TEST_F(PermissionManagerTest, CheckPermissionResultDefault) {
  CheckPermissionResult(PermissionType::MIDI_SYSEX, PermissionStatus::ASK,
                        content::PermissionStatusSource::UNSPECIFIED);
  CheckPermissionResult(PermissionType::NOTIFICATIONS, PermissionStatus::ASK,
                        content::PermissionStatusSource::UNSPECIFIED);
  CheckPermissionResult(PermissionType::GEOLOCATION, PermissionStatus::ASK,
                        content::PermissionStatusSource::UNSPECIFIED);
#if BUILDFLAG(IS_ANDROID)
  CheckPermissionResult(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                        PermissionStatus::GRANTED,
                        content::PermissionStatusSource::UNSPECIFIED);
#endif
}

TEST_F(PermissionManagerTest, CheckPermissionResultAfterSet) {
  SetPermission(PermissionType::GEOLOCATION, PermissionStatus::GRANTED);
  CheckPermissionResult(PermissionType::GEOLOCATION, PermissionStatus::GRANTED,
                        content::PermissionStatusSource::UNSPECIFIED);

  SetPermission(PermissionType::NOTIFICATIONS, PermissionStatus::GRANTED);
  CheckPermissionResult(PermissionType::NOTIFICATIONS,
                        PermissionStatus::GRANTED,
                        content::PermissionStatusSource::UNSPECIFIED);

  SetPermission(PermissionType::MIDI_SYSEX, PermissionStatus::GRANTED);
  CheckPermissionResult(PermissionType::MIDI_SYSEX, PermissionStatus::GRANTED,
                        content::PermissionStatusSource::UNSPECIFIED);

#if BUILDFLAG(IS_ANDROID)
  SetPermission(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                PermissionStatus::GRANTED);
  CheckPermissionResult(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                        PermissionStatus::GRANTED,
                        content::PermissionStatusSource::UNSPECIFIED);
#endif
}

TEST_F(PermissionManagerTest, PermissionIgnoredCleanup) {
  content::WebContents* contents = web_contents();
  PermissionRequestManager::CreateForWebContents(contents);
  PermissionRequestManager* manager =
      PermissionRequestManager::FromWebContents(contents);
  auto prompt_factory = std::make_unique<MockPermissionPromptFactory>(manager);

  NavigateAndCommit(url());

  RequestPermissionFromCurrentDocumentNonBlocking(PermissionType::GEOLOCATION,
                                                  main_rfh());

  EXPECT_FALSE(PendingRequestsEmpty());

  NavigateAndCommit(GURL("https://foobar.com"));

  EXPECT_TRUE(callback_called());
  EXPECT_TRUE(PendingRequestsEmpty());
}

// Check PermissionResult shows requests denied due to insecure
// origins.
TEST_F(PermissionManagerTest, InsecureOrigin) {
  GURL insecure_frame("http://www.example.com/geolocation");
  NavigateAndCommit(insecure_frame);

  content::PermissionResult result = GetPermissionResultForCurrentDocument(
      PermissionType::GEOLOCATION, web_contents()->GetPrimaryMainFrame());

  EXPECT_EQ(PermissionStatus::DENIED, result.status);
  EXPECT_EQ(content::PermissionStatusSource::INSECURE_ORIGIN, result.source);

  GURL secure_frame("https://www.example.com/geolocation");
  NavigateAndCommit(secure_frame);

  result = GetPermissionResultForCurrentDocument(
      PermissionType::GEOLOCATION, web_contents()->GetPrimaryMainFrame());

  EXPECT_EQ(PermissionStatus::ASK, result.status);
  EXPECT_EQ(content::PermissionStatusSource::UNSPECIFIED, result.source);
}

TEST_F(PermissionManagerTest, InsecureOriginIsNotOverridable) {
  const url::Origin kInsecureOrigin =
      url::Origin::Create(GURL("http://example.com/geolocation"));
  const url::Origin kSecureOrigin =
      url::Origin::Create(GURL("https://example.com/geolocation"));
  EXPECT_FALSE(
      IsPermissionOverridable(PermissionType::GEOLOCATION, kInsecureOrigin));
  EXPECT_TRUE(
      IsPermissionOverridable(PermissionType::GEOLOCATION, kSecureOrigin));
}

TEST_F(PermissionManagerTest, MissingContextIsNotOverridable) {
  // Permissions that are not implemented should be denied overridability.
#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
  EXPECT_FALSE(
      IsPermissionOverridable(PermissionType::PROTECTED_MEDIA_IDENTIFIER,
                              url::Origin::Create(GURL("http://localhost"))));
#endif
  EXPECT_TRUE(
      IsPermissionOverridable(PermissionType::MIDI_SYSEX,
                              url::Origin::Create(GURL("http://localhost"))));
}

TEST_F(PermissionManagerTest, KillSwitchOnIsNotOverridable) {
  const url::Origin kLocalHost = url::Origin::Create(GURL("http://localhost"));
  EXPECT_TRUE(IsPermissionOverridable(PermissionType::GEOLOCATION, kLocalHost));

  // Turn on kill switch for GEOLOCATION.
  std::map<std::string, std::string> params;
  params[PermissionUtil::GetPermissionString(
      ContentSettingsType::GEOLOCATION)] =
      PermissionContextBase::kPermissionsKillSwitchBlockedValue;
  base::AssociateFieldTrialParams(
      PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup",
      params);
  base::FieldTrialList::CreateFieldTrial(
      PermissionContextBase::kPermissionsKillSwitchFieldStudy, "TestGroup");

  EXPECT_FALSE(
      IsPermissionOverridable(PermissionType::GEOLOCATION, kLocalHost));
}

TEST_F(PermissionManagerTest, ResetPermission) {
#if BUILDFLAG(IS_ANDROID)
  CheckPermissionStatus(PermissionType::NOTIFICATIONS, PermissionStatus::ASK);
  SetPermission(PermissionType::NOTIFICATIONS, PermissionStatus::GRANTED);
  CheckPermissionStatus(PermissionType::NOTIFICATIONS,
                        PermissionStatus::GRANTED);

  ResetPermission(PermissionType::NOTIFICATIONS, url(), url());

  CheckPermissionStatus(PermissionType::NOTIFICATIONS, PermissionStatus::ASK);
#else
  const char* kOrigin1 = "https://example.com";

  NavigateAndCommit(GURL(kOrigin1));
  content::RenderFrameHost* rfh = main_rfh();

  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::NOTIFICATIONS, rfh));

  PermissionRequestManager::CreateForWebContents(web_contents());
  PermissionRequestManager* manager =
      PermissionRequestManager::FromWebContents(web_contents());
  auto prompt_factory = std::make_unique<MockPermissionPromptFactory>(manager);
  prompt_factory->set_response_type(PermissionRequestManager::ACCEPT_ALL);
  prompt_factory->DocumentOnLoadCompletedInPrimaryMainFrame();

  RequestPermissionFromCurrentDocument(PermissionType::NOTIFICATIONS, rfh);

  EXPECT_EQ(PermissionStatus::GRANTED, GetPermissionStatusForCurrentDocument(
                                           PermissionType::NOTIFICATIONS, rfh));

  ResetPermission(PermissionType::NOTIFICATIONS, GURL(kOrigin1),
                  GURL(kOrigin1));

  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::NOTIFICATIONS, rfh));
#endif
}

TEST_F(PermissionManagerTest, GetPermissionStatusDelegation) {
  const char* kOrigin1 = "https://example.com";
  const char* kOrigin2 = "https://google.com";

  NavigateAndCommit(GURL(kOrigin1));
  content::RenderFrameHost* parent = main_rfh();

  content::RenderFrameHost* child = AddChildRFH(
      parent, GURL(kOrigin2), PermissionsPolicyFeature::kGeolocation);

  // By default the parent should be able to request access, but not the child.
  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::GEOLOCATION, parent));
  // Permission policy is no longer verified in
  // PermissionContextBase, hence in this code a cross-origin
  // iframe is allowed to use permission.
  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::GEOLOCATION, child));

  // When the child requests location a prompt should be displayed for the
  // parent.
  PermissionRequestManager::CreateForWebContents(web_contents());
  PermissionRequestManager* manager =
      PermissionRequestManager::FromWebContents(web_contents());
  auto prompt_factory = std::make_unique<MockPermissionPromptFactory>(manager);
  prompt_factory->set_response_type(PermissionRequestManager::ACCEPT_ALL);
  prompt_factory->DocumentOnLoadCompletedInPrimaryMainFrame();

  RequestPermissionFromCurrentDocument(PermissionType::GEOLOCATION, child);

  EXPECT_TRUE(prompt_factory->RequestOriginSeen(GURL(kOrigin1)));

  // Now the child frame should have location, as well as the parent frame.
  EXPECT_EQ(PermissionStatus::GRANTED,
            GetPermissionStatusForCurrentDocument(PermissionType::GEOLOCATION,
                                                  parent));
  EXPECT_EQ(PermissionStatus::GRANTED, GetPermissionStatusForCurrentDocument(
                                           PermissionType::GEOLOCATION, child));

  // Revoking access from the parent should cause the child not to have access
  // either.
  ResetPermission(PermissionType::GEOLOCATION, GURL(kOrigin1), GURL(kOrigin1));
  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::GEOLOCATION, parent));
  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::GEOLOCATION, child));

  prompt_factory.reset();
}

TEST_F(PermissionManagerTest, GetCanonicalOrigin) {
  GURL requesting("https://requesting.example.com");
  GURL embedding("https://embedding.example.com");

  EXPECT_EQ(embedding,
            permissions::PermissionUtil::GetCanonicalOrigin(
                ContentSettingsType::COOKIES, requesting, embedding));
  EXPECT_EQ(requesting,
            permissions::PermissionUtil::GetCanonicalOrigin(
                ContentSettingsType::NOTIFICATIONS, requesting, embedding));
  EXPECT_EQ(requesting,
            permissions::PermissionUtil::GetCanonicalOrigin(
                ContentSettingsType::STORAGE_ACCESS, requesting, embedding));
}

TEST_F(PermissionManagerTest, RequestPermissionInDifferentStoragePartition) {
  const GURL kOrigin("https://example.com");
  const GURL kOrigin2("https://example2.com");
  const GURL kPartitionedOrigin("https://partitioned.com");
  ScopedPartitionedOriginBrowserClient browser_client(kPartitionedOrigin);

  SetPermission(kOrigin, PermissionType::GEOLOCATION,
                PermissionStatus::GRANTED);

  SetPermission(kOrigin2, PermissionType::GEOLOCATION,
                PermissionStatus::DENIED);
  SetPermission(kOrigin2, PermissionType::NOTIFICATIONS,
                PermissionStatus::GRANTED);

  SetPermission(kPartitionedOrigin, PermissionType::GEOLOCATION,
                PermissionStatus::DENIED);
  SetPermission(kPartitionedOrigin, PermissionType::NOTIFICATIONS,
                PermissionStatus::GRANTED);

  NavigateAndCommit(kOrigin);
  content::RenderFrameHost* parent = main_rfh();

  content::RenderFrameHost* child =
      AddChildRFH(parent, kOrigin2, PermissionsPolicyFeature::kGeolocation);
  content::RenderFrameHost* partitioned_child = AddChildRFH(
      parent, kPartitionedOrigin, PermissionsPolicyFeature::kGeolocation);

  // The parent should have geolocation access which is delegated to child and
  // partitioned_child.
  EXPECT_EQ(PermissionStatus::GRANTED,
            GetPermissionStatusForCurrentDocument(PermissionType::GEOLOCATION,
                                                  parent));
  EXPECT_EQ(PermissionStatus::GRANTED, GetPermissionStatusForCurrentDocument(
                                           PermissionType::GEOLOCATION, child));
  EXPECT_EQ(PermissionStatus::GRANTED,
            GetPermissionStatusForCurrentDocument(PermissionType::GEOLOCATION,
                                                  partitioned_child));

  // The parent should not have notification permission.
  EXPECT_EQ(PermissionStatus::ASK, GetPermissionStatusForCurrentDocument(
                                       PermissionType::NOTIFICATIONS, parent));
  EXPECT_EQ(PermissionStatus::ASK,
            GetPermissionStatusForWorker(
                PermissionType::NOTIFICATIONS, parent->GetProcess(),
                parent->GetLastCommittedOrigin().GetURL()));

  // The non-partitioned child should have notification permission.
  EXPECT_EQ(PermissionStatus::GRANTED,
            GetPermissionStatusForCurrentDocument(PermissionType::NOTIFICATIONS,
                                                  child));
  EXPECT_EQ(PermissionStatus::GRANTED,
            GetPermissionStatusForWorker(
                PermissionType::NOTIFICATIONS, child->GetProcess(),
                child->GetLastCommittedOrigin().GetURL()));

  // The partitioned child should not have notification permission because it
  // belongs to a different StoragePartition, even though its origin would have
  // permission if loaded in a main frame.
  EXPECT_EQ(PermissionStatus::DENIED,
            GetPermissionStatusForCurrentDocument(PermissionType::NOTIFICATIONS,
                                                  partitioned_child));
  EXPECT_EQ(PermissionStatus::DENIED,
            GetPermissionStatusForWorker(
                PermissionType::NOTIFICATIONS, partitioned_child->GetProcess(),
                partitioned_child->GetLastCommittedOrigin().GetURL()));
}

// TODO(crbug.com/377264243): Enable the test when device permission is
// supported in Android
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_UpdatePermissionStatusWithDeviceStatus \
  DISABLED_UpdatePermissionStatusWithDeviceStatus
#else
#define MAYBE_UpdatePermissionStatusWithDeviceStatus \
  UpdatePermissionStatusWithDeviceStatus
#endif
TEST_F(PermissionManagerTest, MAYBE_UpdatePermissionStatusWithDeviceStatus) {
  struct {
    blink::mojom::PermissionStatus initial_status;
    bool has_device_permission;
    bool can_request_device_permission;
    blink::mojom::PermissionStatus expected_status =
        initial_status;  // For most of these test cases the expected status is
                         // the same as the initial status
  } kTests[] = {
      {blink::mojom::PermissionStatus::GRANTED, false, false,
       blink::mojom::PermissionStatus::DENIED},
      {blink::mojom::PermissionStatus::GRANTED, false, true,
       blink::mojom::PermissionStatus::ASK},
      {blink::mojom::PermissionStatus::GRANTED, true, false},
      {blink::mojom::PermissionStatus::GRANTED, true, true},

      {blink::mojom::PermissionStatus::ASK, false, false},
      {blink::mojom::PermissionStatus::ASK, false, true},
      {blink::mojom::PermissionStatus::ASK, true, false},
      {blink::mojom::PermissionStatus::ASK, true, true},

      {blink::mojom::PermissionStatus::DENIED, false, false},
      {blink::mojom::PermissionStatus::DENIED, false, true},
      {blink::mojom::PermissionStatus::DENIED, true, false},
      {blink::mojom::PermissionStatus::DENIED, true, true},
  };

  GURL url("http://google.com");

  for (const auto& test : kTests) {
    SCOPED_TRACE(::testing::Message()
                 << "initial_status:" << test.initial_status
                 << ", expected_status: " << test.expected_status
                 << ", has_device_permission: " << test.has_device_permission
                 << ", can_request_device_permission: "
                 << test.can_request_device_permission);

    SetPermission(blink::PermissionType::NOTIFICATIONS, test.initial_status);
    permissions_client().SetHasDevicePermission(test.has_device_permission);
    permissions_client().SetCanRequestDevicePermission(
        test.can_request_device_permission);

    CheckPermissionStatus(blink::PermissionType::NOTIFICATIONS,
                          test.expected_status,
                          /*should_include_device_status=*/true);
  }
}

TEST_F(PermissionManagerTest,
       GetPermissionContextForNotAddedPermissionContext) {
  PermissionContextBase* context =
      GetPermissionManager()->GetPermissionContextForTesting(
          ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS);

  // Context is null because it is not added to PermissionContextMap.
  EXPECT_TRUE(!context);
}

class PermissionManagerWithGeolocationTest : public PermissionManagerTest {
 public:
  PermissionManagerWithGeolocationTest() {
    feature_list_.InitAndEnableFeature(
        content_settings::features::kApproximateGeolocationPermission);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

TEST_F(PermissionManagerWithGeolocationTest, GetGeolocationPermissionStatus) {
  auto content_settings_type = ContentSettingsType::GEOLOCATION_WITH_OPTIONS;
  auto permission_type = PermissionType::GEOLOCATION;

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kAllowed,
                         PermissionOption::kAllowed});
  CheckPermissionStatus(permission_type, PermissionStatus::GRANTED);

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kAllowed,
                         PermissionOption::kDenied});
  CheckPermissionStatus(permission_type, PermissionStatus::GRANTED);

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kAllowed, PermissionOption::kAsk});
  CheckPermissionStatus(permission_type, PermissionStatus::ASK);

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kAsk, PermissionOption::kAsk});
  CheckPermissionStatus(permission_type, PermissionStatus::ASK);

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kAsk, PermissionOption::kDenied});
  CheckPermissionStatus(permission_type, PermissionStatus::ASK);

  GetHostContentSettingsMap()->SetPermissionSettingDefaultScope(
      url(), url(), content_settings_type,
      GeolocationSetting{PermissionOption::kDenied, PermissionOption::kDenied});
  CheckPermissionStatus(permission_type, PermissionStatus::DENIED);
}

}  // namespace permissions
