// Copyright (c) 2012 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 <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/values.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/active_tab_permission_granter.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/test/browser_side_navigation_test_utils.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extensions_client.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/features/feature_channel.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/value_builder.h"
#include "extensions/test/test_extension_dir.h"

#if defined(OS_CHROMEOS)
#include "base/run_loop.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/extensions/active_tab_permission_granter_delegate_chromeos.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/ui/ash/test_wallpaper_controller.h"
#include "chrome/browser/ui/ash/wallpaper_controller_client.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chromeos/constants/chromeos_switches.h"
#include "chromeos/login/login_state/scoped_test_public_session_login_state.h"
#include "components/account_id/account_id.h"
#include "components/browser_sync/browser_sync_switches.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#endif

using base::DictionaryValue;
using base::ListValue;
using content::BrowserThread;
using content::NavigationController;

namespace extensions {
namespace {

scoped_refptr<const Extension> CreateTestExtension(
    const std::string& name,
    bool has_active_tab_permission,
    bool has_tab_capture_permission) {
  ExtensionBuilder builder(name);
  if (has_active_tab_permission)
    builder.AddPermission("activeTab");
  if (has_tab_capture_permission)
    builder.AddPermission("tabCapture");

  return builder.Build();
}

enum PermittedFeature {
  PERMITTED_NONE,
  PERMITTED_SCRIPT_ONLY,
  PERMITTED_CAPTURE_ONLY,
  PERMITTED_BOTH
};

class ActiveTabPermissionGranterTestDelegate
    : public ActiveTabPermissionGranter::Delegate {
 public:
  ActiveTabPermissionGranterTestDelegate() {}
  ~ActiveTabPermissionGranterTestDelegate() override {}

  // ActiveTabPermissionGranterTestDelegate::Delegate
  bool ShouldGrantActiveTabOrPrompt(const Extension* extension,
                                    content::WebContents* contents) override {
    should_grant_call_count_++;
    return should_grant_;
  }

  void SetShouldGrant(bool should_grant) {
    should_grant_ = should_grant;
  }

  int should_grant_call_count() { return should_grant_call_count_; }

 private:
  bool should_grant_ = false;
  int should_grant_call_count_ = 0;

  DISALLOW_COPY_AND_ASSIGN(ActiveTabPermissionGranterTestDelegate);
};

class ActiveTabTest : public ChromeRenderViewHostTestHarness {
 protected:
  ActiveTabTest()
      : current_channel(version_info::Channel::DEV),
        extension(CreateTestExtension("deadbeef", true, false)),
        another_extension(CreateTestExtension("feedbeef", true, false)),
        extension_without_active_tab(CreateTestExtension("badbeef",
                                                         false,
                                                         false)),
        extension_with_tab_capture(CreateTestExtension("cafebeef",
                                                       true,
                                                       true)) {}

  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();
    TabHelper::CreateForWebContents(web_contents());

    // We need to add extensions to the ExtensionService; else trying to commit
    // any of their URLs fails and redirects to about:blank.
    ExtensionService* service =
        static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))
            ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
                                     base::FilePath(), false);
    service->AddExtension(extension.get());
    service->AddExtension(another_extension.get());
    service->AddExtension(extension_without_active_tab.get());
    service->AddExtension(extension_with_tab_capture.get());
  }

  void TearDown() override {
#if defined(OS_CHROMEOS)
    chromeos::KioskAppManager::Shutdown();
#endif
    ChromeRenderViewHostTestHarness::TearDown();
  }

  int tab_id() { return SessionTabHelper::IdForTab(web_contents()).id(); }

  ActiveTabPermissionGranter* active_tab_permission_granter() {
    return extensions::TabHelper::FromWebContents(web_contents())->
        active_tab_permission_granter();
  }

  bool IsAllowed(const scoped_refptr<const Extension>& extension,
                 const GURL& url) {
    return IsAllowed(extension, url, PERMITTED_BOTH, tab_id());
  }

  bool IsAllowed(const scoped_refptr<const Extension>& extension,
                 const GURL& url,
                 PermittedFeature feature) {
    return IsAllowed(extension, url, feature, tab_id());
  }

  bool IsAllowed(const scoped_refptr<const Extension>& extension,
                 const GURL& url,
                 PermittedFeature feature,
                 int tab_id) {
    const PermissionsData* permissions_data = extension->permissions_data();
    bool script =
        permissions_data->CanAccessPage(url, tab_id, nullptr) &&
        permissions_data->CanRunContentScriptOnPage(url, tab_id, nullptr);
    bool capture = permissions_data->CanCaptureVisiblePage(
        url, tab_id, NULL, extensions::CaptureRequirement::kActiveTabOrAllUrls);
    switch (feature) {
      case PERMITTED_SCRIPT_ONLY:
        return script && !capture;
      case PERMITTED_CAPTURE_ONLY:
        return capture && !script;
      case PERMITTED_BOTH:
        return script && capture;
      case PERMITTED_NONE:
        return !script && !capture;
    }
    NOTREACHED();
    return false;
  }

  bool IsBlocked(const scoped_refptr<const Extension>& extension,
                 const GURL& url) {
    return IsBlocked(extension, url, tab_id());
  }

  bool IsBlocked(const scoped_refptr<const Extension>& extension,
                 const GURL& url,
                 int tab_id) {
    return IsAllowed(extension, url, PERMITTED_NONE, tab_id);
  }

  bool HasTabsPermission(const scoped_refptr<const Extension>& extension) {
    return HasTabsPermission(extension, tab_id());
  }

  bool HasTabsPermission(const scoped_refptr<const Extension>& extension,
                         int tab_id) {
    return extension->permissions_data()->HasAPIPermissionForTab(
        tab_id, APIPermission::kTab);
  }

  bool IsGrantedForTab(const Extension* extension,
                       const content::WebContents* web_contents) {
    return extension->permissions_data()->HasAPIPermissionForTab(
        SessionTabHelper::IdForTab(web_contents).id(), APIPermission::kTab);
  }

  // TODO(justinlin): Remove when tabCapture is moved to stable.
  ScopedCurrentChannel current_channel;

  // An extension with the activeTab permission.
  scoped_refptr<const Extension> extension;

  // Another extension with activeTab (for good measure).
  scoped_refptr<const Extension> another_extension;

  // An extension without the activeTab permission.
  scoped_refptr<const Extension> extension_without_active_tab;

  // An extension with both the activeTab and tabCapture permission.
  scoped_refptr<const Extension> extension_with_tab_capture;
};

TEST_F(ActiveTabTest, GrantToSinglePage) {
  GURL google("http://www.google.com");
  NavigateAndCommit(google);

  // No access unless it's been granted.
  EXPECT_TRUE(IsBlocked(extension, google));
  EXPECT_TRUE(IsBlocked(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  EXPECT_FALSE(HasTabsPermission(extension));
  EXPECT_FALSE(HasTabsPermission(another_extension));
  EXPECT_FALSE(HasTabsPermission(extension_without_active_tab));

  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(
      extension_without_active_tab.get());

  // Granted to extension and extension_without_active_tab, but the latter
  // doesn't have the activeTab permission so not granted.
  EXPECT_TRUE(IsAllowed(extension, google));
  EXPECT_TRUE(IsBlocked(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  // Other subdomains shouldn't be given access.
  GURL mail_google("http://mail.google.com");
  EXPECT_TRUE(IsBlocked(extension, mail_google));
  EXPECT_TRUE(IsBlocked(another_extension, mail_google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, mail_google));

  // Reloading the page should not clear the active permissions, since the
  // user remains on the same site.
  content::NavigationSimulator::Reload(web_contents());

  EXPECT_TRUE(IsAllowed(extension, google));
  EXPECT_TRUE(IsBlocked(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  EXPECT_TRUE(HasTabsPermission(extension));
  EXPECT_FALSE(HasTabsPermission(another_extension));
  EXPECT_FALSE(HasTabsPermission(extension_without_active_tab));

  // And grant a few more times redundantly for good measure.
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());

  EXPECT_TRUE(IsAllowed(extension, google));
  EXPECT_TRUE(IsAllowed(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  // Navigating to a new URL should clear the active permissions.
  GURL chromium("http://www.chromium.org");
  NavigateAndCommit(chromium);

  EXPECT_TRUE(IsBlocked(extension, google));
  EXPECT_TRUE(IsBlocked(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  EXPECT_TRUE(IsBlocked(extension, chromium));
  EXPECT_TRUE(IsBlocked(another_extension, chromium));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));

  EXPECT_FALSE(HasTabsPermission(extension));
  EXPECT_FALSE(HasTabsPermission(another_extension));
  EXPECT_FALSE(HasTabsPermission(extension_without_active_tab));

  // Should be able to grant to multiple extensions at the same time (if they
  // have the activeTab permission, of course).
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(
      extension_without_active_tab.get());

  EXPECT_TRUE(IsBlocked(extension, google));
  EXPECT_TRUE(IsBlocked(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  EXPECT_TRUE(IsAllowed(extension, chromium));
  EXPECT_TRUE(IsAllowed(another_extension, chromium));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));

  // Should be able to go back to URLs that were previously cleared.
  NavigateAndCommit(google);

  active_tab_permission_granter()->GrantIfRequested(extension.get());
  active_tab_permission_granter()->GrantIfRequested(another_extension.get());
  active_tab_permission_granter()->GrantIfRequested(
      extension_without_active_tab.get());

  EXPECT_TRUE(IsAllowed(extension, google));
  EXPECT_TRUE(IsAllowed(another_extension, google));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));

  EXPECT_TRUE(IsBlocked(extension, chromium));
  EXPECT_TRUE(IsBlocked(another_extension, chromium));
  EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));
}

TEST_F(ActiveTabTest, CapturingPagesWithActiveTab) {
  std::vector<GURL> test_urls = {
      GURL("https://example.com"),
      GURL("chrome://version"),
      GURL("chrome://newtab"),
      GURL("http://[2607:f8b0:4005:805::200e]"),
      ExtensionsClient::Get()->GetWebstoreBaseURL(),
      extension->GetResourceURL("test.html"),
      another_extension->GetResourceURL("test.html"),
  };

  const GURL kAboutBlank("about:blank");

  for (const GURL& url : test_urls) {
    SCOPED_TRACE(url);
    NavigateAndCommit(url);
    EXPECT_EQ(url, web_contents()->GetLastCommittedURL());
    // By default, there should be no access.
    EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage(
        url, tab_id(), nullptr /*error*/,
        extensions::CaptureRequirement::kActiveTabOrAllUrls));
    // Granting permission should allow page capture.
    active_tab_permission_granter()->GrantIfRequested(extension.get());
    EXPECT_TRUE(extension->permissions_data()->CanCaptureVisiblePage(
        url, tab_id(), nullptr /*error*/,
        extensions::CaptureRequirement::kActiveTabOrAllUrls));
    // Navigating away should revoke access.
    NavigateAndCommit(kAboutBlank);
    EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage(
        url, tab_id(), nullptr /*error*/,
        extensions::CaptureRequirement::kActiveTabOrAllUrls));
  }
}

TEST_F(ActiveTabTest, Unloading) {
  // Some semi-arbitrary setup.
  GURL google("http://www.google.com");
  NavigateAndCommit(google);

  active_tab_permission_granter()->GrantIfRequested(extension.get());

  EXPECT_TRUE(IsGrantedForTab(extension.get(), web_contents()));
  EXPECT_TRUE(IsAllowed(extension, google));

  // Unloading the extension should clear its tab permissions.
  ExtensionSystem::Get(web_contents()->GetBrowserContext())
      ->extension_service()
      ->DisableExtension(extension->id(), disable_reason::DISABLE_USER_ACTION);

  // Note: can't EXPECT_FALSE(IsAllowed) here because uninstalled extensions
  // are just that... considered to be uninstalled, and the manager might
  // just ignore them from here on.

  // Granting the extension again should give them back.
  active_tab_permission_granter()->GrantIfRequested(extension.get());

  EXPECT_TRUE(IsGrantedForTab(extension.get(), web_contents()));
  EXPECT_TRUE(IsAllowed(extension, google));
}

TEST_F(ActiveTabTest, OnlyActiveTab) {
  GURL google("http://www.google.com");
  NavigateAndCommit(google);

  active_tab_permission_granter()->GrantIfRequested(extension.get());

  EXPECT_TRUE(IsAllowed(extension, google, PERMITTED_BOTH, tab_id()));
  EXPECT_TRUE(IsBlocked(extension, google, tab_id() + 1));
  EXPECT_FALSE(HasTabsPermission(extension, tab_id() + 1));
}

TEST_F(ActiveTabTest, SameDocumentNavigations) {
  GURL google("http://www.google.com");
  NavigateAndCommit(google);

  active_tab_permission_granter()->GrantIfRequested(extension.get());

  // Perform a same-document navigation. The extension should not lose the
  // temporary permission.
  GURL google_h1("http://www.google.com#h1");
  NavigateAndCommit(google_h1);

  EXPECT_TRUE(IsAllowed(extension, google));
  EXPECT_TRUE(IsAllowed(extension, google_h1));

  GURL chromium("http://www.chromium.org");
  NavigateAndCommit(chromium);

  EXPECT_FALSE(IsAllowed(extension, google));
  EXPECT_FALSE(IsAllowed(extension, google_h1));
  EXPECT_FALSE(IsAllowed(extension, chromium));

  active_tab_permission_granter()->GrantIfRequested(extension.get());

  EXPECT_FALSE(IsAllowed(extension, google));
  EXPECT_FALSE(IsAllowed(extension, google_h1));
  EXPECT_TRUE(IsAllowed(extension, chromium));

  GURL chromium_h1("http://www.chromium.org#h1");
  NavigateAndCommit(chromium_h1);

  EXPECT_FALSE(IsAllowed(extension, google));
  EXPECT_FALSE(IsAllowed(extension, google_h1));
  EXPECT_TRUE(IsAllowed(extension, chromium));
  EXPECT_TRUE(IsAllowed(extension, chromium_h1));

  content::NavigationSimulator::Reload(web_contents());

  EXPECT_FALSE(IsAllowed(extension, google));
  EXPECT_FALSE(IsAllowed(extension, google_h1));
  EXPECT_TRUE(IsAllowed(extension, chromium));
  EXPECT_TRUE(IsAllowed(extension, chromium_h1));
}

TEST_F(ActiveTabTest, ChromeUrlGrants) {
  GURL internal("chrome://version");
  NavigateAndCommit(internal);
  active_tab_permission_granter()->GrantIfRequested(
      extension_with_tab_capture.get());
  // Do not grant tabs/hosts permissions for tab.
  EXPECT_TRUE(IsAllowed(extension_with_tab_capture, internal,
                        PERMITTED_CAPTURE_ONLY));
  const PermissionsData* permissions_data =
      extension_with_tab_capture->permissions_data();
  EXPECT_TRUE(permissions_data->HasAPIPermissionForTab(
      tab_id(), APIPermission::kTabCaptureForTab));

  EXPECT_TRUE(IsBlocked(extension_with_tab_capture, internal, tab_id() + 1));
  EXPECT_FALSE(permissions_data->HasAPIPermissionForTab(
      tab_id() + 1, APIPermission::kTabCaptureForTab));
}

class ActiveTabDelegateTest : public ActiveTabTest {
 protected:
  ActiveTabDelegateTest() {
    auto delegate = std::make_unique<ActiveTabPermissionGranterTestDelegate>();
    test_delegate_ = delegate.get();
    ActiveTabPermissionGranter::SetPlatformDelegate(std::move(delegate));
  }

  ~ActiveTabDelegateTest() override {
    ActiveTabPermissionGranter::SetPlatformDelegate(nullptr);
  }

  ActiveTabPermissionGranterTestDelegate* test_delegate_;
};

// Test that the custom platform delegate works as expected.
TEST_F(ActiveTabDelegateTest, Delegate) {
  GURL google("http://www.google.com");
  NavigateAndCommit(google);

  // Not granted because the delegate denies grant.
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  EXPECT_TRUE(IsBlocked(extension, google));

  // This time it's granted because the delegate allows it.
  test_delegate_->SetShouldGrant(true);
  active_tab_permission_granter()->GrantIfRequested(extension.get());
  EXPECT_TRUE(IsAllowed(extension, google));
}

// Regression test for crbug.com/833188.
TEST_F(ActiveTabDelegateTest, DelegateUsedOnlyWhenNeeded) {
  active_tab_permission_granter()->GrantIfRequested(
      extension_without_active_tab.get());

  EXPECT_EQ(0, test_delegate_->should_grant_call_count());
}

#if defined(OS_CHROMEOS)
class ActiveTabManagedSessionTest : public ActiveTabTest {
 protected:
  ActiveTabManagedSessionTest() {}

  void SetUp() override {
    ActiveTabTest::SetUp();

    // Necessary to prevent instantiation of ProfileSyncService, which messes
    // with our signin state below.
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kDisableSync);
    // Necessary because no ProfileManager instance exists in this test.
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        chromeos::switches::kIgnoreUserProfileMappingForTests);

    // Setup, login a public account user.
    const std::string user_id = "public@account.user";
    const std::string user_email = user_id;
    const AccountId account_id =
        AccountId::FromUserEmailGaiaId(user_email, user_id);
    const std::string user_id_hash =
        chromeos::ProfileHelper::Get()->GetUserIdHashByUserIdForTesting(
            user_id);

    local_state_ = std::make_unique<ScopedTestingLocalState>(
        TestingBrowserProcess::GetGlobal());
    wallpaper_controller_client_ =
        std::make_unique<WallpaperControllerClient>();
    wallpaper_controller_client_->InitForTesting(
        test_wallpaper_controller_.CreateInterfacePtr());
    g_browser_process->local_state()->SetString(
        "PublicAccountPendingDataRemoval", user_email);
    user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
                                                   true /* browser_restart */,
                                                   false /* is_child */);
    // Finish initialization - some things are run as separate tasks.
    base::RunLoop().RunUntilIdle();

    google_ = GURL("http://www.google.com");
    NavigateAndCommit(google_);
  }

  void TearDown() override {
    // This one needs to be destructed here so it deregisters itself from
    // CrosSettings before that is destructed down the line inside
    // ChromeRenderViewHostTestHarness::TearDown.
    wallpaper_controller_client_.reset();

    chromeos::ChromeUserManagerImpl::ResetPublicAccountDelegatesForTesting();
    chromeos::ChromeUserManager::Get()->Shutdown();

    ActiveTabTest::TearDown();
  }

  std::unique_ptr<ScopedTestingLocalState> local_state_;
  TestWallpaperController test_wallpaper_controller_;
  std::unique_ptr<WallpaperControllerClient> wallpaper_controller_client_;
  GURL google_;
};

// Test that there's no permission prompt in Managed Sessions (Public Sessions
// v2) for activeTab.
TEST_F(ActiveTabManagedSessionTest, NoPromptInManagedSession) {
  chromeos::ScopedTestPublicSessionLoginState login_state(
      chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT_MANAGED);

  active_tab_permission_granter()->GrantIfRequested(
      extension_with_tab_capture.get());
  EXPECT_TRUE(IsAllowed(extension_with_tab_capture, google_));
}

// Keep the unique_ptr around until callback has been run and don't forget to
// unset the ActiveTabPermissionGranterDelegateChromeOS.
std::unique_ptr<permission_helper::RequestResolvedCallback>
QuitRunLoopOnRequestResolved(base::RunLoop* run_loop) {
  auto callback = std::make_unique<permission_helper::RequestResolvedCallback>(
      base::BindRepeating([](base::RunLoop* run_loop, const PermissionIDSet&) {
        run_loop->Quit();
      }, run_loop));
  ActiveTabPermissionGranterDelegateChromeOS::
      SetRequestResolvedCallbackForTesting(callback.get());
  return callback;
}

// Test that the platform delegate is being set and the activeTab permission is
// prompted for in Public Sessions.
TEST_F(ActiveTabManagedSessionTest,
       DelegateIsSetAndPromptIsShownInPublicSession) {
  chromeos::ScopedTestPublicSessionLoginState login_state(
      chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT);
  // Grant and verify.
  {
    ScopedTestDialogAutoConfirm auto_confirm(
        ScopedTestDialogAutoConfirm::ACCEPT);

    // RunLoop needed to resolve the permission dialog.
    base::RunLoop run_loop;
    auto cb = QuitRunLoopOnRequestResolved(&run_loop);
    active_tab_permission_granter()->GrantIfRequested(extension.get());
    run_loop.Run();
    EXPECT_TRUE(IsBlocked(extension, google_));

    active_tab_permission_granter()->GrantIfRequested(extension.get());
    EXPECT_TRUE(IsAllowed(extension, google_));
  }

  // Deny and verify. Use a different extension so it doesn't trigger the
  // cache.
  {
    ScopedTestDialogAutoConfirm auto_confirm(
        ScopedTestDialogAutoConfirm::CANCEL);

    base::RunLoop run_loop;
    auto cb = QuitRunLoopOnRequestResolved(&run_loop);
    active_tab_permission_granter()->GrantIfRequested(another_extension.get());
    run_loop.Run();
    EXPECT_TRUE(IsBlocked(another_extension, google_));

    active_tab_permission_granter()->GrantIfRequested(another_extension.get());
    EXPECT_TRUE(IsBlocked(another_extension, google_));
  }

  // Cleanup.
  ActiveTabPermissionGranterDelegateChromeOS::
      SetRequestResolvedCallbackForTesting(nullptr);
}
#endif  // defined(OS_CHROMEOS)

// An active tab test that includes an ExtensionService.
class ActiveTabWithServiceTest : public ExtensionServiceTestBase {
 public:
  ActiveTabWithServiceTest() {}

  void SetUp() override;
  void TearDown() override;

 private:
  DISALLOW_COPY_AND_ASSIGN(ActiveTabWithServiceTest);
};

void ActiveTabWithServiceTest::SetUp() {
  ExtensionServiceTestBase::SetUp();
  content::BrowserSideNavigationSetUp();
}

void ActiveTabWithServiceTest::TearDown() {
  content::BrowserSideNavigationTearDown();
  ExtensionServiceTestBase::TearDown();
}

// Tests that an extension can only capture file:// URLs with the active tab
// permission when it has file access granted.
// Regression test for https://crbug.com/810220.
TEST_F(ActiveTabWithServiceTest, FileURLs) {
  InitializeEmptyExtensionService();

  TestExtensionDir test_dir;
  test_dir.WriteManifest(R"(
    {
      "name": "Active Tab Capture With File Urls",
      "description": "Testing activeTab on file urls",
      "version": "0.1",
      "manifest_version": 2,
      "permissions": ["activeTab"]
    })");

  ChromeTestExtensionLoader loader(profile());
  loader.set_allow_file_access(false);
  scoped_refptr<const Extension> extension =
      loader.LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);
  const std::string id = extension->id();
  ASSERT_TRUE(registry()->enabled_extensions().Contains(id));

  EXPECT_FALSE(util::AllowFileAccess(id, profile()));

  std::unique_ptr<content::WebContents> web_contents(
      content::WebContentsTester::CreateTestWebContents(profile(), nullptr));
  ASSERT_TRUE(web_contents);

  const GURL file_url("file:///foo");
  ASSERT_TRUE(content::WebContentsTester::For(web_contents.get()));
  content::WebContentsTester::For(web_contents.get())
      ->NavigateAndCommit(file_url);
  EXPECT_EQ(file_url, web_contents->GetLastCommittedURL());

  TabHelper::CreateForWebContents(web_contents.get());
  ActiveTabPermissionGranter* permission_granter =
      TabHelper::FromWebContents(web_contents.get())
          ->active_tab_permission_granter();
  ASSERT_TRUE(permission_granter);
  const int tab_id = SessionTabHelper::IdForTab(web_contents.get()).id();
  EXPECT_NE(extension_misc::kUnknownTabId, tab_id);

  EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage(
      web_contents->GetLastCommittedURL(), tab_id, nullptr,
      extensions::CaptureRequirement::kActiveTabOrAllUrls));

  permission_granter->GrantIfRequested(extension.get());
  EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage(
      web_contents->GetLastCommittedURL(), tab_id, nullptr,
      extensions::CaptureRequirement::kActiveTabOrAllUrls));

  permission_granter->RevokeForTesting();
  TestExtensionRegistryObserver observer(registry(), id);
  // This will reload the extension, so we need to reset the extension pointer.
  util::SetAllowFileAccess(id, profile(), true);
  extension = observer.WaitForExtensionLoaded();
  ASSERT_TRUE(extension);

  EXPECT_FALSE(extension->permissions_data()->CanCaptureVisiblePage(
      web_contents->GetLastCommittedURL(), tab_id, nullptr,
      extensions::CaptureRequirement::kActiveTabOrAllUrls));
  permission_granter->GrantIfRequested(extension.get());
  EXPECT_TRUE(extension->permissions_data()->CanCaptureVisiblePage(
      web_contents->GetLastCommittedURL(), tab_id, nullptr,
      extensions::CaptureRequirement::kActiveTabOrAllUrls));
}

}  // namespace
}  // namespace extensions
