// 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 <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 ExtensionService;
class ExtensionServiceTest;
class SkBitmap;
struct WebApplicationInfo;

namespace base {
class SequencedTaskRunner;
}

namespace extensions {
class CrxInstallError;
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|.
  void InstallCrx(const base::FilePath& 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_; }

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

  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.
  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(bool success);

  // 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();

  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_;

  // Whether to create an app shortcut after successful installation. This is
  // set based on the user's selection in the UI and can only ever be true for
  // apps.
  bool create_app_shortcut_;

  // 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 Extenion::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_;

  DISALLOW_COPY_AND_ASSIGN(CrxInstaller);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_
