Commit 474151c8 authored by Mark Banner's avatar Mark Banner
Browse files

Bug 1810766 - Move parts of search engine add-on upgrade process to...

Bug 1810766 - Move parts of search engine add-on upgrade process to AddonSearchEngine. r=search-reviewers,daleharvey

This moves the upgrade parts which are to do with getting details from the add-on manager.

Differential Revision: https://phabricator.services.mozilla.com/D167050
parent d80619ec
Loading
Loading
Loading
Loading
+93 −19
Original line number Diff line number Diff line
@@ -82,30 +82,76 @@ export class AddonSearchEngine extends SearchEngine {
   *   may be overriding some of the WebExtension's settings.
   */
  async init({ extension, locale, config }) {
    let manifest = await this.#getManifestForLocale(extension, locale);
    let { baseURI, manifest } = await this.#getExtensionDetailsForLocale(
      extension,
      locale
    );

    this.#initFromManifest(extension.baseURI, manifest, locale, config);
    this.#initFromManifest(baseURI, manifest, locale, config);
  }

  /**
   * Update this engine based on new manifest, used during
   * webextension upgrades.
   * Manages updates to this engine.
   *
   * @param {string} extensionBaseURI
   *   The Base URI of the WebExtension.
   * @param {object} manifest
   *   An object representing the WebExtensions' manifest.
   * @param {string} locale
   *   The locale that is being used for the WebExtension.
   * @param {object} [configuration]
   * @param {object} options
   *   The options object.
   * @param {object} [options.configuration]
   *   The search engine configuration for application provided engines, that
   *   may be overriding some of the WebExtension's settings.
   * @param {object} [options.extension]
   *   The extension associated with this search engine, if known.
   * @param {object} [options.manifest]
   *   The extension's manifest associated with this search engine, if known.
   * @param {string} [options.locale]
   *   The locale to use from the extension for getting details of the search
   *   engine.
   */
  updateFromManifest(extensionBaseURI, manifest, locale, configuration = {}) {
    this._urls = [];
    this._iconMapObj = null;
    this.#initFromManifest(extensionBaseURI, manifest, locale, configuration);
    lazy.SearchUtils.notifyAction(this, lazy.SearchUtils.MODIFIED_TYPE.CHANGED);
  async update({ configuration, extension, manifest, locale }) {
    let baseURI = extension?.baseURI;
    if (!manifest) {
      ({ baseURI, manifest } = await this.#getExtensionDetailsForLocale(
        extension,
        locale
      ));
    }
    let originalName = this.name;
    let name = manifest.chrome_settings_overrides.search_provider.name.trim();
    if (originalName != name && Services.search.getEngineByName(name)) {
      throw new Error("Can't upgrade to the same name as an existing engine");
    }

    this.#updateFromManifest(baseURI, manifest, locale, configuration);
  }

  /**
   * This will update the add-on search engine if there is no name change.
   *
   * @param {object} options
   *   The options object.
   * @param {object} [options.configuration]
   *   The search engine configuration for application provided engines, that
   *   may be overriding some of the WebExtension's settings.
   * @param {string} [options.locale]
   *   The locale to use from the extension for getting details of the search
   *   engine.
   * @returns {boolean}
   *   Returns true if the engine was updated, false otherwise.
   */
  async updateIfNoNameChange({ configuration, locale }) {
    let { baseURI, manifest } = await this.#getExtensionDetailsForLocale(
      null,
      locale
    );

    if (
      this.name !=
      manifest.chrome_settings_overrides.search_provider.name.trim()
    ) {
      return false;
    }

    this.#updateFromManifest(baseURI, manifest, locale, configuration);
    return true;
  }

  /**
@@ -289,6 +335,27 @@ export class AddonSearchEngine extends SearchEngine {
    );
  }

  /**
   * Update this engine based on new manifest, used during
   * webextension upgrades.
   *
   * @param {string} extensionBaseURI
   *   The Base URI of the WebExtension.
   * @param {object} manifest
   *   An object representing the WebExtensions' manifest.
   * @param {string} locale
   *   The locale that is being used for the WebExtension.
   * @param {object} [configuration]
   *   The search engine configuration for application provided engines, that
   *   may be overriding some of the WebExtension's settings.
   */
  #updateFromManifest(extensionBaseURI, manifest, locale, configuration = {}) {
    this._urls = [];
    this._iconMapObj = null;
    this.#initFromManifest(extensionBaseURI, manifest, locale, configuration);
    lazy.SearchUtils.notifyAction(this, lazy.SearchUtils.MODIFIED_TYPE.CHANGED);
  }

  /**
   * Get the localized manifest from the WebExtension for the given locale or
   * manifest default locale.
@@ -298,7 +365,7 @@ export class AddonSearchEngine extends SearchEngine {
   * ignoring the user's current locale. The user's current locale is taken into
   * account within the configuration, just not in the WebExtension.
   *
   * @param {object} extension
   * @param {object} [extension]
   *   The extension to get the manifest from.
   * @param {string} locale
   *   The locale to load from the WebExtension. If this is `DEFAULT_TAG`, then
@@ -306,7 +373,14 @@ export class AddonSearchEngine extends SearchEngine {
   * @returns {object}
   *   The loaded manifest.
   */
  async #getManifestForLocale(extension, locale) {
  async #getExtensionDetailsForLocale(extension, locale) {
    // If we haven't been passed an extension object, then go and find it.
    if (!extension) {
      extension = (
        await AddonSearchEngine.getWebExtensionPolicy(this._extensionID)
      ).extension;
    }

    let manifest = extension.manifest;

    // If the locale we want from the WebExtension is the extension's default
@@ -320,7 +394,7 @@ export class AddonSearchEngine extends SearchEngine {
    if (localeToLoad) {
      manifest = await extension.getLocalizedManifest(localeToLoad);
    }
    return manifest;
    return { baseURI: extension.baseURI, manifest };
  }

  /**
+26 −83
Original line number Diff line number Diff line
@@ -1783,7 +1783,6 @@ export class SearchService {
          e.webExtension.locale == engine._locale
      );

      let policy, manifest, locale;
      if (index == -1) {
        // No engines directly match on id and locale, however, check to see
        // if we have a new entry that matches on id and name - we might just
@@ -1799,47 +1798,36 @@ export class SearchService {
          continue;
        }

        policy = await lazy.AddonSearchEngine.getWebExtensionPolicy(
          engine._extensionID
        // Update the index so we can handle the updating below.
        index = configEngines.findIndex(
          e =>
            e.webExtension.id == replacementEngines[0].webExtension.id &&
            e.webExtension.locale == replacementEngines[0].webExtension.locale
        );
        locale =
        let locale =
          replacementEngines[0].webExtension.locale ||
          lazy.SearchUtils.DEFAULT_TAG;
        manifest = await this.#getManifestForLocale(policy.extension, locale);

        // If the name is different, then we must treat the engine as different,
        // and go through the remove and add cycle, rather than modifying the
        // existing one.
        if (
          engine.name !=
          manifest.chrome_settings_overrides.search_provider.name.trim()
        ) {
        let hasUpdated = await engine.updateIfNoNameChange({
          configuration: configEngines[index],
          locale,
        });
        if (!hasUpdated) {
          // No matching name, so just remove it.
          engine.pendingRemoval = true;
          continue;
        }

        // Update the index so we can handle the updating below.
        index = configEngines.findIndex(
          e =>
            e.webExtension.id == replacementEngines[0].webExtension.id &&
            e.webExtension.locale == replacementEngines[0].webExtension.locale
        );
      } else {
        // This is an existing engine that we should update (we don't know if
        // the configuration for this engine has changed or not).
        policy = await lazy.AddonSearchEngine.getWebExtensionPolicy(
          engine._extensionID
        );
        locale = engine._locale;
        manifest = await this.#getManifestForLocale(policy.extension, locale);
        await engine.update({
          configuration: configEngines[index],
          locale: engine._locale,
        });
      }
      engine.updateFromManifest(
        policy.extension.baseURI,
        manifest,
        locale,
        configEngines[index]
      );

      configEngines.splice(index, 1);
    }
@@ -2645,31 +2633,24 @@ export class SearchService {
    let extensionEngines = await this.getEnginesByExtensionID(extension.id);

    for (let engine of extensionEngines) {
      let isDefault = engine == this.defaultEngine;
      let isDefaultPrivate = engine == this.defaultPrivateEngine;

      let originalName = engine.name;
      let locale = engine._locale || lazy.SearchUtils.DEFAULT_TAG;
      let manifest = await this.#getManifestForLocale(extension, locale);
      let configuration =
        engines.find(
          e =>
            e.webExtension.id == extension.id && e.webExtension.locale == locale
        ) ?? {};

      let appDefaultName = engine.name;
      let name = manifest.chrome_settings_overrides.search_provider.name.trim();
      if (appDefaultName != name && this.getEngineByName(name)) {
        throw new Error("Can't upgrade to the same name as an existing engine");
      }

      let isDefault = engine == this.defaultEngine;
      let isDefaultPrivate = engine == this.defaultPrivateEngine;

      engine.updateFromManifest(
        extension.baseURI,
        manifest,
      await engine.update({
        configuration,
        extension,
        locale,
        configuration
      );
      });

      if (appDefaultName != engine.name) {
      if (engine.name != originalName) {
        if (isDefault) {
          this._settings.setVerifiedMetaDataAttribute(
            "defaultEngineId",
@@ -3447,23 +3428,19 @@ export class SearchService {
   */
  async _makeEngineFromConfig(config) {
    lazy.logConsole.debug("_makeEngineFromConfig:", config);
    let policy = await lazy.AddonSearchEngine.getWebExtensionPolicy(
      config.webExtension.id
    );
    let locale =
      "locale" in config.webExtension
        ? config.webExtension.locale
        : lazy.SearchUtils.DEFAULT_TAG;

    let engine = new lazy.AddonSearchEngine({
      isAppProvided: policy.extension.isAppProvided,
      isAppProvided: true,
      details: {
        extensionID: policy.extension.id,
        extensionID: config.webExtension.id,
        locale,
      },
    });
    await engine.init({
      extension: policy.extension,
      locale,
      config,
    });
@@ -3514,40 +3491,6 @@ export class SearchService {
      newCurrentEngine
    );
  }

  /**
   * Get the localized manifest from the WebExtension for the given locale or
   * manifest default locale.
   *
   * The search service configuration overloads the add-on manager concepts of
   * locales, and forces particular locales within the WebExtension to be used,
   * ignoring the user's current locale. The user's current locale is taken into
   * account within the configuration, just not in the WebExtension.
   *
   * @param {object} extension
   *   The extension to get the manifest from.
   * @param {string} locale
   *   The locale to load from the WebExtension. If this is `DEFAULT_TAG`, then
   *   the default locale is loaded.
   * @returns {object}
   *   The loaded manifest.
   */
  async #getManifestForLocale(extension, locale) {
    let manifest = extension.manifest;

    // If the locale we want from the WebExtension is the extension's default
    // then we get that from the manifest here. We do this because if we
    // are reloading due to the locale change, the add-on manager might not
    // have updated the WebExtension's manifest to the new version by the
    // time we hit this code.
    let localeToLoad =
      locale == lazy.SearchUtils.DEFAULT_TAG ? manifest.default_locale : locale;

    if (localeToLoad) {
      manifest = await extension.getLocalizedManifest(localeToLoad);
    }
    return manifest;
  }
} // end SearchService class

var engineUpdateService = {