// 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 "chrome/browser/extensions/crx_installer.h"

#include <stddef.h>

#include <utility>

#include "base/at_exit.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
#include "chrome/browser/extensions/test_extension_dir.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/web_application_info.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/install/crx_install_error.h"
#include "extensions/browser/management_policy.h"
#include "extensions/browser/notification_types.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/file_util.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
#include "chromeos/chromeos_switches.h"
#include "components/user_manager/scoped_user_manager.h"
#endif

class SkBitmap;

namespace {

const char kAppUrl[] = "http://www.google.com";
const char kAppTitle[] = "Test title";
const char kAppDescription[] = "Test description";

}  // anonymous namespace

namespace extensions {

namespace {

class MockInstallPrompt;

// This class holds information about things that happen with a
// MockInstallPrompt. We create the MockInstallPrompt but need to pass
// ownership of it to CrxInstaller, so it isn't safe to hang this data on
// MockInstallPrompt itself becuase we can't guarantee it's lifetime.
class MockPromptProxy {
 public:
  explicit MockPromptProxy(content::WebContents* web_contents);
  ~MockPromptProxy();

  bool did_succeed() const { return !extension_id_.empty(); }
  const std::string& extension_id() { return extension_id_; }
  bool confirmation_requested() const { return confirmation_requested_; }
  const base::string16& error() const { return error_; }

  void set_extension_id(const std::string& id) { extension_id_ = id; }
  void set_confirmation_requested(bool requested) {
    confirmation_requested_ = requested;
  }
  void set_error(const base::string16& error) { error_ = error; }

  std::unique_ptr<ExtensionInstallPrompt> CreatePrompt();

 private:

  // Data used to create a prompt.
  content::WebContents* web_contents_;

  // Data reported back to us by the prompt we created.
  bool confirmation_requested_;
  std::string extension_id_;
  base::string16 error_;

  std::unique_ptr<ScopedTestDialogAutoConfirm> auto_confirm;

  DISALLOW_COPY_AND_ASSIGN(MockPromptProxy);
};

SkBitmap CreateSquareBitmap(int size) {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(size, size);
  bitmap.eraseColor(SK_ColorRED);
  return bitmap;
}

WebApplicationInfo::IconInfo CreateIconInfoWithBitmap(int size) {
  WebApplicationInfo::IconInfo icon_info;
  icon_info.width = size;
  icon_info.height = size;
  icon_info.data = CreateSquareBitmap(size);
  return icon_info;
}

WebApplicationInfo CreateWebAppInfo(const char* title,
                                    const char* description,
                                    const char* app_url,
                                    int size) {
  WebApplicationInfo web_app_info;
  web_app_info.title = base::UTF8ToUTF16(title);
  web_app_info.description = base::UTF8ToUTF16(description);
  web_app_info.app_url = GURL(app_url);
  web_app_info.scope = GURL(app_url);

  web_app_info.icons.push_back(CreateIconInfoWithBitmap(size));

  return web_app_info;
}

class MockInstallPrompt : public ExtensionInstallPrompt {
 public:
  MockInstallPrompt(content::WebContents* web_contents,
                    MockPromptProxy* proxy) :
      ExtensionInstallPrompt(web_contents),
      proxy_(proxy) {}

  // Overriding some of the ExtensionInstallUI API.
  void OnInstallSuccess(const Extension* extension, SkBitmap* icon) override {
    proxy_->set_extension_id(extension->id());
    proxy_->set_confirmation_requested(did_call_show_dialog());
  }
  void OnInstallFailure(const CrxInstallError& error) override {
    proxy_->set_error(error.message());
    proxy_->set_confirmation_requested(did_call_show_dialog());
  }

 private:
  MockPromptProxy* proxy_;

  DISALLOW_COPY_AND_ASSIGN(MockInstallPrompt);
};

MockPromptProxy::MockPromptProxy(content::WebContents* web_contents)
    : web_contents_(web_contents),
      confirmation_requested_(false),
      auto_confirm(new ScopedTestDialogAutoConfirm(
          ScopedTestDialogAutoConfirm::ACCEPT)) {
}

MockPromptProxy::~MockPromptProxy() {}

std::unique_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
  return std::unique_ptr<MockInstallPrompt>(
      new MockInstallPrompt(web_contents_, this));
}

std::unique_ptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
    Browser* browser) {
  return std::make_unique<MockPromptProxy>(
      browser->tab_strip_model()->GetActiveWebContents());
}

class ManagementPolicyMock : public extensions::ManagementPolicy::Provider {
 public:
  ManagementPolicyMock() {}

  std::string GetDebugPolicyProviderName() const override {
    return "ManagementPolicyMock";
  }

  bool UserMayLoad(const Extension* extension,
                   base::string16* error) const override {
    if (error)
      *error = base::UTF8ToUTF16("Dummy error message");
    return false;
  }
};

}  // namespace

class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
 protected:
  std::unique_ptr<WebstoreInstaller::Approval> GetApproval(
      const char* manifest_dir,
      const std::string& id,
      bool strict_manifest_checks) {
    std::unique_ptr<WebstoreInstaller::Approval> result;

    base::ScopedAllowBlockingForTesting allow_io;
    base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
    std::string error;
    std::unique_ptr<base::DictionaryValue> parsed_manifest(
        file_util::LoadManifest(ext_path, &error));
    if (!parsed_manifest.get() || !error.empty())
      return result;

    return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
        browser()->profile(), id, std::move(parsed_manifest),
        strict_manifest_checks);
  }

  ExtensionService* extension_service() {
    return extensions::ExtensionSystem::Get(browser()->profile())
        ->extension_service();
  }

  const Extension* GetInstalledExtension(const std::string& extension_id) {
    return extension_service()->GetInstalledExtension(extension_id);
  }

  std::unique_ptr<base::ScopedTempDir> UnpackedCrxTempDir() {
    auto temp_dir = std::make_unique<base::ScopedTempDir>();
    EXPECT_TRUE(temp_dir->CreateUniqueTempDir());
    EXPECT_TRUE(base::PathExists(temp_dir->GetPath()));

    base::FilePath unpacked_path = test_data_dir_.AppendASCII("good_unpacked");
    EXPECT_TRUE(base::PathExists(unpacked_path));
    EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir->GetPath(), false));

    return temp_dir;
  }

  // Helper function that creates a file at |relative_path| within |directory|
  // and fills it with |content|.
  bool AddFileToDirectory(const base::FilePath& directory,
                          const base::FilePath& relative_path,
                          const std::string& content) const {
    const base::FilePath full_path = directory.Append(relative_path);
    if (!CreateDirectory(full_path.DirName()))
      return false;
    const int result =
        base::WriteFile(full_path, content.data(), content.size());
    return (static_cast<size_t>(result) == content.size());
  }

  void AddExtension(const std::string& extension_id,
                    const std::string& version) {
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    ASSERT_TRUE(base::PathExists(temp_dir.GetPath()));

    base::FilePath foo_js(FILE_PATH_LITERAL("foo.js"));
    base::FilePath bar_html(FILE_PATH_LITERAL("bar/bar.html"));
    ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), foo_js, "hello"))
        << "Failed to write " << temp_dir.GetPath().value() << "/"
        << foo_js.value();
    ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), bar_html, "world"));

    ExtensionBuilder builder;
    builder.SetManifest(DictionaryBuilder()
                            .Set("name", "My First Extension")
                            .Set("version", version)
                            .Set("manifest_version", 2)
                            .Build());
    builder.SetID(extension_id);
    builder.SetPath(temp_dir.GetPath());
    ExtensionRegistry::Get(browser()->profile())->AddEnabled(builder.Build());

    const Extension* extension = GetInstalledExtension(extension_id);
    ASSERT_NE(nullptr, extension);
    ASSERT_EQ(version, extension->VersionString());
  }

  static void InstallerCallback(base::OnceClosure quit_closure,
                                CrxInstaller::InstallerResultCallback callback,
                                bool success) {
    if (!callback.is_null())
      std::move(callback).Run(success);
    std::move(quit_closure).Run();
  }

  void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
                       std::unique_ptr<ExtensionInstallPrompt> prompt,
                       CrxInstaller::InstallerResultCallback callback,
                       const base::FilePath& crx_path) {
    base::RunLoop run_loop;

    scoped_refptr<CrxInstaller> installer(
        CrxInstaller::Create(extension_service(), std::move(prompt), approval));
    installer->set_allow_silent_install(true);
    installer->set_is_gallery_install(true);
    installer->set_installer_callback(
        base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
                       run_loop.QuitWhenIdleClosure(), std::move(callback)));
    installer->InstallCrx(crx_path);

    run_loop.Run();
  }

  void RunCrxInstallerFromUnpackedDirectory(
      std::unique_ptr<ExtensionInstallPrompt> prompt,
      CrxInstaller::InstallerResultCallback callback,
      const std::string& extension_id,
      const std::string& public_key,
      const base::FilePath& crx_directory) {
    base::RunLoop run_loop;

    scoped_refptr<CrxInstaller> installer(
        CrxInstaller::Create(extension_service(), std::move(prompt)));
    installer->set_allow_silent_install(true);
    installer->set_is_gallery_install(true);
    installer->set_installer_callback(
        base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
                       run_loop.QuitWhenIdleClosure(), std::move(callback)));
    installer->set_delete_source(true);
    installer->InstallUnpackedCrx(extension_id, public_key, crx_directory);

    run_loop.Run();
  }

  void RunUpdateExtension(std::unique_ptr<ExtensionInstallPrompt> prompt,
                          const std::string& extension_id,
                          const std::string& public_key,
                          const base::FilePath& unpacked_dir,
                          CrxInstaller::InstallerResultCallback callback) {
    base::RunLoop run_loop;

    scoped_refptr<CrxInstaller> installer(
        CrxInstaller::Create(extension_service(), std::move(prompt)));
    installer->set_delete_source(true);
    installer->set_installer_callback(
        base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
                       run_loop.QuitWhenIdleClosure(), std::move(callback)));
    installer->UpdateExtensionFromUnpackedCrx(extension_id, public_key,
                                              unpacked_dir);

    run_loop.Run();
  }

  // Installs a crx from |crx_relpath| (a path relative to the extension test
  // data dir) with expected id |id|.
  void InstallWithPrompt(const char* ext_relpath,
                         const std::string& id,
                         CrxInstaller::InstallerResultCallback callback,
                         MockPromptProxy* mock_install_prompt) {
    base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);

    std::unique_ptr<WebstoreInstaller::Approval> approval;
    if (!id.empty())
      approval = GetApproval(ext_relpath, id, true);

    base::FilePath crx_path = PackExtension(ext_path);
    EXPECT_FALSE(crx_path.empty());
    RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
                    std::move(callback), crx_path);

    EXPECT_TRUE(mock_install_prompt->did_succeed());
  }

  // Installs an extension and checks that it has scopes granted IFF
  // |record_oauth2_grant| is true.
  void CheckHasEmptyScopesAfterInstall(
      const std::string& ext_relpath,
      CrxInstaller::InstallerResultCallback callback,
      bool record_oauth2_grant) {
    std::unique_ptr<MockPromptProxy> mock_prompt =
        CreateMockPromptProxyForBrowser(browser());

    InstallWithPrompt("browsertest/scopes", std::string(), std::move(callback),
                      mock_prompt.get());

    std::unique_ptr<const PermissionSet> permissions =
        ExtensionPrefs::Get(browser()->profile())
            ->GetGrantedPermissions(mock_prompt->extension_id());
    ASSERT_TRUE(permissions.get());
  }

  void InstallWebAppAndVerifyNoErrors() {
    scoped_refptr<CrxInstaller> crx_installer(
        CrxInstaller::CreateSilent(extension_service()));
    crx_installer->set_error_on_unsupported_requirements(true);
    crx_installer->InstallWebApp(
        CreateWebAppInfo(kAppTitle, kAppDescription, kAppUrl, 64));
    EXPECT_TRUE(WaitForCrxInstallerDone());
    ASSERT_TRUE(crx_installer->extension());
  }
};

class ExtensionCrxInstallerTestWithExperimentalApis
    : public ExtensionCrxInstallerTest {
 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionCrxInstallerTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       ExperimentalExtensionFromGallery) {
  // Gallery-installed extensions should have their experimental permission
  // preserved, since we allow the Webstore to make that decision.
  const Extension* extension = InstallExtensionFromWebstore(
      test_data_dir_.AppendASCII("experimental.crx"), 1);
  ASSERT_TRUE(extension);
  EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
      APIPermission::kExperimental));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       ExperimentalExtensionFromOutsideGallery) {
  // Non-gallery-installed extensions should lose their experimental
  // permission if the flag isn't enabled.
  const Extension* extension = InstallExtension(
      test_data_dir_.AppendASCII("experimental.crx"), 1);
  ASSERT_TRUE(extension);
  EXPECT_FALSE(extension->permissions_data()->HasAPIPermission(
      APIPermission::kExperimental));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       ExperimentalExtensionFromOutsideGalleryWithFlag) {
  // Non-gallery-installed extensions should maintain their experimental
  // permission if the flag is enabled.
  const Extension* extension = InstallExtension(
      test_data_dir_.AppendASCII("experimental.crx"), 1);
  ASSERT_TRUE(extension);
  EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
      APIPermission::kExperimental));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       PlatformAppCrx) {
  EXPECT_TRUE(InstallExtension(
      test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, BlockedFileTypes) {
  const Extension* extension =
      InstallExtension(test_data_dir_.AppendASCII("blocked_file_types.crx"), 1);
  base::ScopedAllowBlockingForTesting allow_io;
  EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.html")));
  EXPECT_TRUE(base::PathExists(extension->path().AppendASCII("test.nexe")));
  EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test1.EXE")));
  EXPECT_FALSE(base::PathExists(extension->path().AppendASCII("test2.exe")));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowedThemeFileTypes) {
  const Extension* extension = InstallExtension(
      test_data_dir_.AppendASCII("theme_with_extension.crx"), 1);
  ASSERT_TRUE(extension);
  const base::FilePath& path = extension->path();
  base::ScopedAllowBlockingForTesting allow_io;
  EXPECT_TRUE(
      base::PathExists(path.AppendASCII("images/theme_frame_camo.PNG")));
  EXPECT_TRUE(
      base::PathExists(path.AppendASCII("images/theme_ntp_background.png")));
  EXPECT_TRUE(base::PathExists(
      path.AppendASCII("images/theme_ntp_background_norepeat.png")));
  EXPECT_TRUE(
      base::PathExists(path.AppendASCII("images/theme_toolbar_camo.png")));
  EXPECT_TRUE(base::PathExists(path.AppendASCII("images/redirect_target.GIF")));
  EXPECT_TRUE(base::PathExists(path.AppendASCII("test.image.bmp")));
  EXPECT_TRUE(
      base::PathExists(path.AppendASCII("test_image_with_no_extension")));

  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.html")));
  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.nexe")));
  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test1.EXE")));
  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test2.exe")));
  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.txt")));
  EXPECT_FALSE(base::PathExists(path.AppendASCII("non_images/test.css")));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       PackAndInstallExtensionFromDownload) {
  std::unique_ptr<base::AutoReset<bool>> allow_offstore_install =
      download_crx_util::OverrideOffstoreInstallAllowedForTesting(true);

  const int kNumDownloadsExpected = 1;

  base::FilePath crx_path = PackExtension(
      test_data_dir_.AppendASCII("common/background_page"));
  ASSERT_FALSE(crx_path.empty());
  std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
  GURL url = GURL(std::string("file:///").append(crx_path_string));

  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());
  download_crx_util::SetMockInstallPromptForTesting(
      mock_prompt->CreatePrompt());

  content::DownloadManager* download_manager =
      content::BrowserContext::GetDownloadManager(browser()->profile());

  std::unique_ptr<content::DownloadTestObserver> observer(
      new content::DownloadTestObserverTerminal(
          download_manager, kNumDownloadsExpected,
          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, WindowOpenDisposition::CURRENT_TAB,
      ui_test_utils::BROWSER_TEST_NONE);

  EXPECT_TRUE(WaitForCrxInstallerDone());
  EXPECT_TRUE(mock_prompt->confirmation_requested());
}

// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
// true.
#if defined(OS_WIN)
#define MAYBE_GrantScopes DISABLED_GrantScopes
#define MAYBE_GrantScopes_WithCallback DISABLED_GrantScopes_WithCallback
#else
#define MAYBE_GrantScopes GrantScopes
#define MAYBE_GrantScopes_WithCallback GrantScopes_WithCallback
#endif
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       MAYBE_GrantScopes) {
  EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
      "browsertest/scopes", CrxInstaller::InstallerResultCallback(), true));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       MAYBE_GrantScopes_WithCallback) {
  EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
      "browsertest/scopes",
      base::BindOnce([](bool success) { EXPECT_TRUE(success); }), true));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       DoNotGrantScopes) {
  EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
      "browsertest/scopes", CrxInstaller::InstallerResultCallback(), false));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTestWithExperimentalApis,
                       DoNotGrantScopes_WithCallback) {
  EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall(
      "browsertest/scopes",
      base::BindOnce([](bool success) { EXPECT_TRUE(success); }), false));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) {
  const bool kTestData[] = {false, true};

  for (size_t i = 0; i < arraysize(kTestData); ++i) {
    std::unique_ptr<MockPromptProxy> mock_prompt =
        CreateMockPromptProxyForBrowser(browser());

    scoped_refptr<CrxInstaller> crx_installer(
        CrxInstaller::Create(extension_service(), mock_prompt->CreatePrompt()));
    crx_installer->set_install_cause(
        extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);

    if (kTestData[i]) {
      crx_installer->set_off_store_install_allow_reason(
          CrxInstaller::OffStoreInstallAllowedInTest);
    }

    base::RunLoop run_loop;
    crx_installer->set_installer_callback(
        base::BindOnce(&ExtensionCrxInstallerTest::InstallerCallback,
                       run_loop.QuitWhenIdleClosure(),
                       CrxInstaller::InstallerResultCallback()));
    crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
    // The |mock_prompt| will quit running the loop once the |crx_installer|
    // is done.
    run_loop.Run();
    EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
    EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
        kTestData[i];
    if (kTestData[i]) {
      EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i];
    } else {
      EXPECT_EQ(l10n_util::GetStringUTF16(
          IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
          mock_prompt->error()) << kTestData[i];
    }
  }
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
  base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
  crx_path = crx_path.AppendASCII("theme_hidpi.crx");

  ASSERT_TRUE(InstallExtension(crx_path, 1));

  const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
  ExtensionRegistry* registry = ExtensionRegistry::Get(
      browser()->profile());
  const extensions::Extension* extension =
     registry->enabled_extensions().GetByID(extension_id);
  ASSERT_TRUE(extension);
  EXPECT_EQ(extension_id, extension->id());

  UninstallExtension(extension_id);
  EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallDelayedUntilNextUpdate) {
  const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
  base::FilePath base_path = test_data_dir_.AppendASCII("delayed_install");

  ExtensionService* service = extension_service();
  ASSERT_TRUE(service);
  ExtensionRegistry* registry = ExtensionRegistry::Get(
      browser()->profile());
  ASSERT_TRUE(registry);

  // Install version 1 of the test extension. This extension does not have
  // a background page but does have a browser action.
  base::FilePath v1_path = PackExtension(base_path.AppendASCII("v1"));
  ASSERT_FALSE(v1_path.empty());
  ASSERT_TRUE(InstallExtension(v1_path, 1));
  const extensions::Extension* extension =
     registry->enabled_extensions().GetByID(extension_id);
  ASSERT_TRUE(extension);
  ASSERT_EQ(extension_id, extension->id());
  ASSERT_EQ("1.0", extension->version().GetString());

  // Make test extension non-idle by opening the extension's options page.
  ExtensionTabUtil::OpenOptionsPage(extension, browser());
  WaitForExtensionNotIdle(extension_id);

  // Install version 2 of the extension and check that it is indeed delayed.
  base::FilePath v2_path = PackExtension(base_path.AppendASCII("v2"));
  ASSERT_FALSE(v2_path.empty());
  ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v2_path, 0));

  ASSERT_EQ(1u, service->delayed_installs()->size());
  extension = registry->enabled_extensions().GetByID(extension_id);
  ASSERT_EQ("1.0", extension->version().GetString());

  // Make the extension idle again by navigating away from the options page.
  // This should not trigger the delayed install.
  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
  WaitForExtensionIdle(extension_id);
  ASSERT_EQ(1u, service->delayed_installs()->size());
  extension = registry->enabled_extensions().GetByID(extension_id);
  ASSERT_EQ("1.0", extension->version().GetString());

  // Install version 3 of the extension. Because the extension is idle,
  // this install should succeed.
  base::FilePath v3_path = PackExtension(base_path.AppendASCII("v3"));
  ASSERT_FALSE(v3_path.empty());
  ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v3_path, 0));
  extension = registry->enabled_extensions().GetByID(extension_id);
  ASSERT_EQ("3.0", extension->version().GetString());

  // The version 2 delayed install should be cleaned up, and finishing
  // delayed extension installation shouldn't break anything.
  ASSERT_EQ(0u, service->delayed_installs()->size());
  service->MaybeFinishDelayedInstallations();
  extension = registry->enabled_extensions().GetByID(extension_id);
  ASSERT_EQ("3.0", extension->version().GetString());
}

#if defined(FULL_SAFE_BROWSING)
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
  scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
      new FakeSafeBrowsingDatabaseManager(true));
  Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);

  blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");

  base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
                                          .AppendASCII("theme_hidpi.crx");
  EXPECT_FALSE(InstallExtension(crx_path, 0));
}
#endif

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  // We want to simulate the case where the webstore sends a more recent
  // version of the manifest, but the downloaded .crx file is old since
  // the newly published version hasn't fully propagated to all the download
  // servers yet. So load the v2 manifest, but then install the v1 crx file.
  std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
  std::unique_ptr<WebstoreInstaller::Approval> approval =
      GetApproval("crx_installer/v2_no_permission_change/", id, false);

  RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
                  CrxInstaller::InstallerResultCallback(),
                  test_data_dir_.AppendASCII("crx_installer/v1.crx"));

  EXPECT_TRUE(mock_prompt->did_succeed());
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       NonStrictManifestCheck_WithCallback) {
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  // We want to simulate the case where the webstore sends a more recent
  // version of the manifest, but the downloaded .crx file is old since
  // the newly published version hasn't fully propagated to all the download
  // servers yet. So load the v2 manifest, but then install the v1 crx file.
  const std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
  std::unique_ptr<WebstoreInstaller::Approval> approval =
      GetApproval("crx_installer/v2_no_permission_change/", id, false);

  RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
                  base::BindOnce([](bool success) { EXPECT_TRUE(success); }),
                  test_data_dir_.AppendASCII("crx_installer/v1.crx"));

  EXPECT_TRUE(mock_prompt->did_succeed());
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_FolderDoesNotExist) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());

  const base::FilePath folder = temp_dir.GetPath().AppendASCII("abcdef");
  EXPECT_FALSE(base::PathExists(folder));

  const std::string public_key = "123456";
  RunCrxInstallerFromUnpackedDirectory(
      mock_prompt->CreatePrompt(),
      base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
      std::string(), public_key, folder);

  EXPECT_FALSE(mock_prompt->did_succeed());
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_EmptyFolder) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
  EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));

  const std::string public_key = "123456";
  RunCrxInstallerFromUnpackedDirectory(
      mock_prompt->CreatePrompt(),
      base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
      std::string(), public_key, temp_dir.GetPath());

  EXPECT_FALSE(mock_prompt->did_succeed());
  EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallUnpackedCrx_InvalidPublicKey) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
  EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));

  const base::FilePath unpacked_path =
      test_data_dir_.AppendASCII("good_unpacked");
  EXPECT_TRUE(base::PathExists(unpacked_path));
  EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false));

  const std::string public_key = "123456";
  RunCrxInstallerFromUnpackedDirectory(
      mock_prompt->CreatePrompt(),
      base::BindOnce([](bool success) { EXPECT_FALSE(success); }),
      std::string(), public_key, temp_dir.GetPath());

  EXPECT_FALSE(mock_prompt->did_succeed());
  EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallUnpackedCrx_Success) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  base::ScopedTempDir temp_dir;
  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
  EXPECT_TRUE(base::PathExists(temp_dir.GetPath()));

  const base::FilePath unpacked_path =
      test_data_dir_.AppendASCII("good_unpacked");
  EXPECT_TRUE(base::PathExists(unpacked_path));
  EXPECT_TRUE(base::CopyDirectory(unpacked_path, temp_dir.GetPath(), false));

  const std::string public_key =
      "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
      "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
      "kDuI7caxEGUucpP7GJRRHnm8Sx+"
      "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
  RunCrxInstallerFromUnpackedDirectory(
      mock_prompt->CreatePrompt(),
      base::BindOnce([](bool success) { EXPECT_TRUE(success); }), std::string(),
      public_key, temp_dir.GetPath());

  EXPECT_TRUE(mock_prompt->did_succeed());
  EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_NewExtension) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  // Update won't work as the extension doesn't exist.
  const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
  const std::string public_key =
      "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
      "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
      "kDuI7caxEGUucpP7GJRRHnm8Sx+"
      "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";
  ASSERT_EQ(nullptr, GetInstalledExtension(extension_id));
  auto temp_dir = UnpackedCrxTempDir();
  RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
                     temp_dir->GetPath(), base::BindOnce([](bool success) {
                       EXPECT_FALSE(success);
                     }));

  // The unpacked folder should be deleted.
  EXPECT_FALSE(mock_prompt->did_succeed());
  EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));
  EXPECT_EQ(nullptr, GetInstalledExtension(extension_id));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_UpdateExistingExtension) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
  const std::string public_key =
      "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
      "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
      "kDuI7caxEGUucpP7GJRRHnm8Sx+"
      "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";

  // Test updating an existing extension.
  AddExtension(extension_id, "0.0");

  auto temp_dir = UnpackedCrxTempDir();
  RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
                     temp_dir->GetPath(), base::BindOnce([](bool success) {
                       EXPECT_TRUE(success);
                     }));

  EXPECT_TRUE(mock_prompt->did_succeed());

  // The unpacked folder should be deleted.
  EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));

  const Extension* extension = GetInstalledExtension(extension_id);
  ASSERT_NE(nullptr, extension);
  EXPECT_EQ("1.0", extension->VersionString());
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_InvalidPublicKey) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  const std::string extension_id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
  const std::string public_key = "invalid public key";

  // Test updating an existing extension.
  AddExtension(extension_id, "0.0");

  auto temp_dir = UnpackedCrxTempDir();
  RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
                     temp_dir->GetPath(), base::BindOnce([](bool success) {
                       EXPECT_FALSE(success);
                     }));

  EXPECT_FALSE(mock_prompt->did_succeed());

  // The unpacked folder should be deleted.
  EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));

  const Extension* extension = GetInstalledExtension(extension_id);
  ASSERT_NE(nullptr, extension);
  EXPECT_EQ("0.0", extension->VersionString());
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       UpdateExtensionFromUnpackedCrx_WrongPublicKey) {
  base::ScopedAllowBlockingForTesting allow_io;
  std::unique_ptr<MockPromptProxy> mock_prompt =
      CreateMockPromptProxyForBrowser(browser());

  const std::string extension_id = "gllekhaobjnhgeagipipnkpmmmpchacm";
  const std::string public_key =
      "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/"
      "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j"
      "kDuI7caxEGUucpP7GJRRHnm8Sx+"
      "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB";

  // Test updating an existing extension.
  AddExtension(extension_id, "0.0");

  auto temp_dir = UnpackedCrxTempDir();
  RunUpdateExtension(mock_prompt->CreatePrompt(), extension_id, public_key,
                     temp_dir->GetPath(), base::BindOnce([](bool success) {
                       EXPECT_FALSE(success);
                     }));

  EXPECT_FALSE(mock_prompt->did_succeed());

  // The unpacked folder should be deleted.
  EXPECT_FALSE(base::PathExists(temp_dir->GetPath()));

  const Extension* extension = GetInstalledExtension(extension_id);
  ASSERT_NE(nullptr, extension);
  EXPECT_EQ("0.0", extension->VersionString());
}

#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
  // kiosk_only is whitelisted from non-chromeos.
  base::FilePath crx_path =
      test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
  EXPECT_FALSE(InstallExtension(crx_path, 0));
  // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
  // lifetime of |user_manager|.
  chromeos::FakeChromeUserManager* fake_user_manager =
      new chromeos::FakeChromeUserManager();
  const AccountId account_id(AccountId::FromUserEmail("example@example.com"));
  fake_user_manager->AddKioskAppUser(account_id);
  fake_user_manager->LoginUser(account_id);
  user_manager::ScopedUserManager scoped_user_manager(
      base::WrapUnique(fake_user_manager));
  EXPECT_TRUE(InstallExtension(crx_path, 1));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      chromeos::switches::kEnableExtensionAssetsSharing);
  base::ScopedTempDir cache_dir;
  ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
  ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
      cache_dir.GetPath());

  base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
  const extensions::Extension* extension = InstallExtension(
      crx_path, 1, extensions::Manifest::EXTERNAL_PREF);
  base::FilePath extension_path = extension->path();
  EXPECT_TRUE(cache_dir.GetPath().IsParent(extension_path));
  base::ScopedAllowBlockingForTesting allow_io;
  EXPECT_TRUE(base::PathExists(extension_path));

  std::string extension_id = extension->id();
  UninstallExtension(extension_id);
  ExtensionRegistry* registry = ExtensionRegistry::Get(
      browser()->profile());
  EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));

  content::RunAllTasksUntilIdle();

  EXPECT_FALSE(base::PathExists(extension_path));
}
#endif

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) {
  scoped_refptr<CrxInstaller> crx_installer(
      CrxInstaller::CreateSilent(extension_service()));
  crx_installer->set_do_not_sync(true);
  crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
  EXPECT_TRUE(WaitForCrxInstallerDone());
  ASSERT_TRUE(crx_installer->extension());

  const ExtensionPrefs* extension_prefs =
      ExtensionPrefs::Get(browser()->profile());
  EXPECT_TRUE(extension_prefs->DoNotSync(crx_installer->extension()->id()));
  EXPECT_FALSE(extensions::util::ShouldSync(crx_installer->extension(),
                                            browser()->profile()));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {
  ManagementPolicyMock policy;
  extensions::ExtensionSystem::Get(profile())
      ->management_policy()
      ->RegisterProvider(&policy);

  base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
  EXPECT_FALSE(InstallExtension(crx_path, 0));
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallWebApp) {
  InstallWebAppAndVerifyNoErrors();
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
                       InstallWebAppSucceedsWithBlockPolicy) {
  // Verify that the install still works when a management policy blocking
  // extension installation is in force. Bookmark apps are special-cased to skip
  // these checks (see https://crbug.com/545541).
  ManagementPolicyMock policy;
  extensions::ExtensionSystem::Get(profile())
      ->management_policy()
      ->RegisterProvider(&policy);

  InstallWebAppAndVerifyNoErrors();
}

IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, UpdateWithFileAccess) {
  base::FilePath ext_source =
      test_data_dir_.AppendASCII("permissions").AppendASCII("files");
  base::FilePath crx_with_file_permission = PackExtension(ext_source);
  ASSERT_FALSE(crx_with_file_permission.empty());

  ExtensionService* service = extension_service();

  const std::string extension_id("bdkapipdccfifhdghmblnenbbncfcpid");
  {
    // Install extension.
    scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
    installer->InstallCrx(crx_with_file_permission);
    EXPECT_TRUE(WaitForCrxInstallerDone());
    const Extension* extension = installer->extension();
    ASSERT_TRUE(extension);
    // IDs must match, otherwise the test doesn't make any sense.
    ASSERT_EQ(extension_id, extension->id());
    // Sanity check: File access should be disabled by default.
    EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
    EXPECT_FALSE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
  }

  {
    // Uninstall and re-install the extension. Any previously granted file
    // permissions should be gone.
    ExtensionPrefs::Get(profile())->SetAllowFileAccess(extension_id, true);
    EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
    UninstallExtension(extension_id);
    EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));

    scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
    installer->InstallCrx(crx_with_file_permission);
    EXPECT_TRUE(WaitForCrxInstallerDone());
    const Extension* extension = installer->extension();
    ASSERT_TRUE(extension);
    ASSERT_EQ(extension_id, extension->id());
    EXPECT_FALSE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
    EXPECT_FALSE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
  }

  {
    // Grant file access and update the extension. File access should be kept.
    ExtensionPrefs::Get(profile())->SetAllowFileAccess(extension_id, true);
    EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
    base::FilePath crx_update_with_file_permission = PackExtension(ext_source);

    scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service));
    installer->InstallCrx(crx_update_with_file_permission);
    EXPECT_TRUE(WaitForCrxInstallerDone());
    const Extension* extension = installer->extension();
    ASSERT_TRUE(extension);
    ASSERT_EQ(extension_id, extension->id());
    EXPECT_TRUE(ExtensionPrefs::Get(profile())->AllowFileAccess(extension_id));
    EXPECT_TRUE(extension->creation_flags() & Extension::ALLOW_FILE_ACCESS);
  }
}

}  // namespace extensions
