// 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.

#ifndef CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_

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

#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/version.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/common/extensions/extension_constants.h"
#include "components/sync/model/string_ordinal.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/install_flag.h"
#include "extensions/browser/preload_check.h"
#include "extensions/browser/sandboxed_unpacker.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"

class ExtensionServiceTest;
class SkBitmap;
struct WebApplicationInfo;

namespace base {
class SequencedTaskRunner;
}

namespace service_manager {
class Connector;
}

namespace extensions {
class CrxInstallError;
class ExtensionService;
class ExtensionUpdaterTest;
class PreloadCheckGroup;

// This class installs a crx file into a profile.
//
// Installing a CRX is a multi-step process, including unpacking the crx,
// validating it, prompting the user, and installing. Since many of these
// steps must occur on the file thread, this class contains a copy of all data
// necessary to do its job. (This also minimizes external dependencies for
// easier testing).
//
// Lifetime management:
//
// This class is ref-counted by each call it makes to itself on another thread,
// and by UtilityProcessHost.
//
// Additionally, we hold a reference to our own client so that it lives at least
// long enough to receive the result of unpacking.
//
// IMPORTANT: Callers should keep a reference to a CrxInstaller while they are
// working with it, eg:
//
// scoped_refptr<CrxInstaller> installer(new CrxInstaller(...));
// installer->set_foo();
// installer->set_bar();
// installer->InstallCrx(...);
//
// Installation is aborted if the extension service learns that Chrome is
// terminating during the install. We can't listen for the app termination
// notification here in this class because it can be destroyed on any thread
// and won't safely be able to clean up UI thread notification listeners.
class CrxInstaller : public SandboxedUnpackerClient {
 public:
  // A callback to be executed when the install finishes.
  using InstallerResultCallback = ExtensionSystem::InstallUpdateCallback;

  // Used in histograms; do not change order.
  enum OffStoreInstallAllowReason {
    OffStoreInstallDisallowed,
    OffStoreInstallAllowedFromSettingsPage,
    OffStoreInstallAllowedBecausePref,
    OffStoreInstallAllowedInTest,
    NumOffStoreInstallAllowReasons
  };

  // Extensions will be installed into service->install_directory(), then
  // registered with |service|. This does a silent install - see below for
  // other options.
  static scoped_refptr<CrxInstaller> CreateSilent(ExtensionService* service);

  // Same as above, but use |client| to generate a confirmation prompt.
  static scoped_refptr<CrxInstaller> Create(
      ExtensionService* service,
      std::unique_ptr<ExtensionInstallPrompt> client);

  // Same as the previous method, except use the |approval| to bypass the
  // prompt. Note that the caller retains ownership of |approval|.
  static scoped_refptr<CrxInstaller> Create(
      ExtensionService* service,
      std::unique_ptr<ExtensionInstallPrompt> client,
      const WebstoreInstaller::Approval* approval);

  // Install the crx in |source_file|. The file must be a CRX3. A publisher
  // proof in the file is required unless off-webstore installation is allowed.
  void InstallCrx(const base::FilePath& source_file);

  // Install the crx in |source_file|.
  void InstallCrxFile(const CRXFileInfo& source_file);

  // Install the unpacked crx in |unpacked_dir|.
  // If |delete_source_| is true, |unpacked_dir| will be removed at the end of
  // the installation.
  void InstallUnpackedCrx(const std::string& extension_id,
                          const std::string& public_key,
                          const base::FilePath& unpacked_dir);

  // Convert the specified user script into an extension and install it.
  void InstallUserScript(const base::FilePath& source_file,
                         const GURL& download_url);

  // Convert the specified web app into an extension and install it.
  void InstallWebApp(const WebApplicationInfo& web_app);

  // Update the extension |extension_id| with the unpacked crx in
  // |unpacked_dir|.
  // If |delete_source_| is true, |unpacked_dir| will be removed at the end of
  // the update.
  void UpdateExtensionFromUnpackedCrx(const std::string& extension_id,
                                      const std::string& public_key,
                                      const base::FilePath& unpacked_dir);

  void OnInstallPromptDone(ExtensionInstallPrompt::Result result);

  void InitializeCreationFlagsForUpdate(const Extension* extension,
                                        const int initial_flags);

  int creation_flags() const { return creation_flags_; }
  void set_creation_flags(int val) { creation_flags_ = val; }

  const base::FilePath& source_file() const { return source_file_; }

  Manifest::Location install_source() const {
    return install_source_;
  }
  void set_install_source(Manifest::Location source) {
    install_source_ = source;
  }

  const std::string& expected_id() const { return expected_id_; }
  void set_expected_id(const std::string& val) { expected_id_ = val; }

  // Expected SHA256 hash sum for the package.
  const std::string& expected_hash() const { return expected_hash_; }
  void set_expected_hash(const std::string& val) { expected_hash_ = val; }

  bool hash_check_failed() const { return hash_check_failed_; }
  void set_hash_check_failed(bool val) { hash_check_failed_ = val; }

  // Set the exact version the installed extension should have. If
  // |fail_install_if_unexpected| is true, installation will fail if the actual
  // version doesn't match. If it is false, the installation will still
  // be performed, but the extension will not be granted any permissions.
  void set_expected_version(const base::Version& val,
                            bool fail_install_if_unexpected) {
    expected_version_ = val;
    fail_install_if_unexpected_version_ = fail_install_if_unexpected;
  }

  bool delete_source() const { return delete_source_; }
  void set_delete_source(bool val) { delete_source_ = val; }

  bool allow_silent_install() const { return allow_silent_install_; }
  void set_allow_silent_install(bool val) { allow_silent_install_ = val; }

  bool grant_permissions() const { return grant_permissions_; }
  void set_grant_permissions(bool val) { grant_permissions_ = val; }

  bool is_gallery_install() const {
    return (creation_flags_ & Extension::FROM_WEBSTORE) > 0;
  }
  void set_is_gallery_install(bool val) {
    if (val)
      creation_flags_ |= Extension::FROM_WEBSTORE;
    else
      creation_flags_ &= ~Extension::FROM_WEBSTORE;
  }

  // If |apps_require_extension_mime_type_| is set to true, be sure to set
  // |original_mime_type_| as well.
  void set_apps_require_extension_mime_type(
      bool apps_require_extension_mime_type) {
    apps_require_extension_mime_type_ = apps_require_extension_mime_type;
  }

  void set_original_mime_type(const std::string& original_mime_type) {
    original_mime_type_ = original_mime_type;
  }

  extension_misc::CrxInstallCause install_cause() const {
    return install_cause_;
  }
  void set_install_cause(extension_misc::CrxInstallCause install_cause) {
    install_cause_ = install_cause;
  }

  OffStoreInstallAllowReason off_store_install_allow_reason() const {
    return off_store_install_allow_reason_;
  }
  void set_off_store_install_allow_reason(OffStoreInstallAllowReason reason) {
    off_store_install_allow_reason_ = reason;
  }

  void set_page_ordinal(const syncer::StringOrdinal& page_ordinal) {
    page_ordinal_ = page_ordinal;
  }

  void set_error_on_unsupported_requirements(bool val) {
    error_on_unsupported_requirements_ = val;
  }

  void set_install_immediately(bool val) {
    set_install_flag(kInstallFlagInstallImmediately, val);
  }
  void set_do_not_sync(bool val) {
    set_install_flag(kInstallFlagDoNotSync, val);
  }

  void set_installer_callback(InstallerResultCallback callback) {
    installer_callback_ = std::move(callback);
  }

  bool did_handle_successfully() const { return did_handle_successfully_; }

  Profile* profile() { return profile_; }

  const Extension* extension() { return extension_.get(); }

  // The currently installed version of the extension, for updates. Will be
  // invalid if this isn't an update.
  const base::Version& current_version() const { return current_version_; }

  static void set_connector_for_test(service_manager::Connector* connector) {
    connector_for_test_ = connector;
  }

 private:
  friend class ::ExtensionServiceTest;
  friend class ExtensionUpdaterTest;
  friend class BookmarkAppInstallerTest;

  CrxInstaller(base::WeakPtr<ExtensionService> service_weak,
               std::unique_ptr<ExtensionInstallPrompt> client,
               const WebstoreInstaller::Approval* approval);
  ~CrxInstaller() override;

  // Converts the source user script to an extension.
  void ConvertUserScriptOnFileThread();

  // Converts the source web app to an extension.
  void ConvertWebAppOnFileThread(const WebApplicationInfo& web_app);

  // Called after OnUnpackSuccess as a last check to see whether the install
  // should complete.
  base::Optional<CrxInstallError> AllowInstall(const Extension* extension);

  // SandboxedUnpackerClient
  void OnUnpackFailure(const CrxInstallError& error) override;
  void OnUnpackSuccess(
      const base::FilePath& temp_dir,
      const base::FilePath& extension_dir,
      std::unique_ptr<base::DictionaryValue> original_manifest,
      const Extension* extension,
      const SkBitmap& install_icon,
      const base::Optional<int>& dnr_ruleset_checksum) override;

  // Called on the UI thread to start the requirements, policy and blacklist
  // checks on the extension.
  void CheckInstall();

  // Runs on the UI thread. Callback from PreloadCheckGroup.
  void OnInstallChecksComplete(const PreloadCheck::Errors& errors);

  // Runs on the UI thread. Confirms the installation to the ExtensionService.
  void ConfirmInstall();

  // Runs on the UI thread. Updates the creation flags for the extension and
  // calls CompleteInstall().
  void UpdateCreationFlagsAndCompleteInstall();

  // Runs on File thread. Install the unpacked extension into the profile and
  // notify the frontend.
  void CompleteInstall();

  // Reloads extension on File thread and reports installation result back
  // to UI thread.
  void ReloadExtensionAfterInstall(const base::FilePath& version_dir);

  // Result reporting.
  void ReportFailureFromFileThread(const CrxInstallError& error);
  void ReportFailureFromUIThread(const CrxInstallError& error);
  void ReportSuccessFromFileThread();
  void ReportSuccessFromUIThread();
  void NotifyCrxInstallBegin();
  void NotifyCrxInstallComplete(const base::Optional<CrxInstallError>& error);

  // Deletes temporary directory and crx file if needed.
  void CleanupTempFiles();

  // Checks whether the current installation is initiated by the user from
  // the extension settings page to update an existing extension or app.
  void CheckUpdateFromSettingsPage();

  // Show re-enable prompt if the update is initiated from the settings page
  // and needs additional permissions.
  void ConfirmReEnable();

  // Returns the connector to the ServiceManager.
  service_manager::Connector* GetConnector() const;

  void set_install_flag(int flag, bool val) {
    if (val)
      install_flags_ |= flag;
    else
      install_flags_ &= ~flag;
  }

  // The Profile the extension is being installed in.
  Profile* profile_;

  // The extension being installed.
  scoped_refptr<const Extension> extension_;

  // The file we're installing.
  base::FilePath source_file_;

  // The URL the file was downloaded from.
  GURL download_url_;

  // The directory extensions are installed to.
  const base::FilePath install_directory_;

  // The location the installation came from (bundled with Chromium, registry,
  // manual install, etc). This metadata is saved with the installation if
  // successful. Defaults to INTERNAL.
  Manifest::Location install_source_;

  // Indicates whether the user has already approved the extension to be
  // installed. If true, |expected_manifest_| and |expected_id_| must match
  // those of the CRX.
  bool approved_;

  // For updates, external and webstore installs we have an ID we're expecting
  // the extension to contain.
  std::string expected_id_;

  // An expected hash sum for the .crx file.
  std::string expected_hash_;

  // True if installation failed due to a hash sum mismatch.
  bool hash_check_failed_;

  // A parsed copy of the expected manifest, before any transformations like
  // localization have taken place. If |approved_| is true, then the
  // extension's manifest must match this for the install to proceed.
  std::unique_ptr<Manifest> expected_manifest_;

  // The level of checking when comparing the actual manifest against
  // the |expected_manifest_|.
  WebstoreInstaller::ManifestCheckLevel expected_manifest_check_level_;

  // If valid, specifies the minimum version we'll install. Installation will
  // fail if the actual version is smaller.
  base::Version minimum_version_;

  // If valid, contains the expected version of the extension we're installing.
  // Important for external sources, where claiming the wrong version could
  // cause unnecessary unpacking of an extension at every restart.
  // See also |fail_install_if_unexpected_version_|!
  base::Version expected_version_;

  // If true, installation will fail if the actual version doesn't match
  // |expected_version_|. If false, the extension will still be installed, but
  // not granted any permissions.
  bool fail_install_if_unexpected_version_;

  // Whether manual extension installation is enabled. We can't just check this
  // before trying to install because themes and bookmark apps are special-cased
  // to always be allowed.
  bool extensions_enabled_;

  // Whether we're supposed to delete the source file on destruction. Defaults
  // to false.
  bool delete_source_;

  // The ordinal of the NTP apps page |extension_| will be shown on.
  syncer::StringOrdinal page_ordinal_;

  // A parsed copy of the unmodified original manifest, before any
  // transformations like localization have taken place.
  std::unique_ptr<Manifest> original_manifest_;

  // If valid, contains the current version of the extension we're
  // installing (for upgrades).
  base::Version current_version_;

  // The icon we will display in the installation UI, if any.
  std::unique_ptr<SkBitmap> install_icon_;

  // The temp directory extension resources were unpacked to. We own this and
  // must delete it when we are done with it.
  base::FilePath temp_dir_;

  // The frontend we will report results back to.
  base::WeakPtr<ExtensionService> service_weak_;

  // The client we will work with to do the installation. This can be NULL, in
  // which case the install is silent.
  std::unique_ptr<ExtensionInstallPrompt> client_;

  // The root of the unpacked extension directory. This is a subdirectory of
  // temp_dir_, so we don't have to delete it explicitly.
  base::FilePath unpacked_extension_root_;

  // True when the CRX being installed was just downloaded.
  // Used to trigger extra checks before installing.
  bool apps_require_extension_mime_type_;

  // Allows for the possibility of a normal install (one in which a |client|
  // is provided in the ctor) to proceed without showing the permissions prompt
  // dialog.
  bool allow_silent_install_;

  // Allows for the possibility of an installation without granting any
  // permissions to the extension.
  bool grant_permissions_;

  // The value of the content type header sent with the CRX.
  // Ignorred unless |require_extension_mime_type_| is true.
  std::string original_mime_type_;

  // What caused this install?  Used only for histograms that report
  // on failure rates, broken down by the cause of the install.
  extension_misc::CrxInstallCause install_cause_;

  // Creation flags to use for the extension.  These flags will be used
  // when calling Extension::Create() by the crx installer.
  int creation_flags_;

  // Whether to allow off store installation.
  OffStoreInstallAllowReason off_store_install_allow_reason_;

  // Whether the installation was handled successfully. This is used to
  // indicate to the client whether the file should be removed and any UI
  // initiating the installation can be removed. This is different than whether
  // there was an error; if there was an error that rejects installation we
  // still consider the installation 'handled'.
  bool did_handle_successfully_;

  // Whether we should produce an error if the manifest declares requirements
  // that are not met. If false and there is an unmet requirement, the install
  // will continue but the extension will be distabled.
  bool error_on_unsupported_requirements_;

  // Sequenced task runner where file I/O operations will be performed.
  scoped_refptr<base::SequencedTaskRunner> installer_task_runner_;

  // Used to show the install dialog.
  ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback_;

  // Whether the update is initiated by the user from the extension settings
  // page.
  bool update_from_settings_page_;

  // The flags for ExtensionService::OnExtensionInstalled.
  int install_flags_;

  // The checksum for the indexed ruleset corresponding to the Declarative Net
  // Request API.
  base::Optional<int> dnr_ruleset_checksum_;

  // Checks that may run before installing the extension.
  std::unique_ptr<PreloadCheck> policy_check_;
  std::unique_ptr<PreloadCheck> requirements_check_;
  std::unique_ptr<PreloadCheck> blacklist_check_;

  // Runs the above checks.
  std::unique_ptr<PreloadCheckGroup> check_group_;

  // Invoked when the install is completed.
  InstallerResultCallback installer_callback_;

  static service_manager::Connector* connector_for_test_;

  DISALLOW_COPY_AND_ASSIGN(CrxInstaller);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_
