Commit 63ffcb2e authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

BB 43525: Skip Remote Settings for search engine customization.

Also, add some bundled search engines.
parent 65e79d7d
Loading
Loading
Loading
Loading
+16 −38
Original line number Diff line number Diff line
@@ -112,6 +112,10 @@ class IconHandler {
      await this.#buildIconMap();
    }

    if (AppConstants.BASE_BROWSER_VERSION) {
      return this.#iconMap.get(engineIdentifier);
    }

    let iconList = this.#iconMap.get(this.getKey(engineIdentifier)) || [];
    return iconList.filter(r =>
      this.#identifierMatches(engineIdentifier, r.engineIdentifiers)
@@ -128,29 +132,7 @@ class IconHandler {
   *   source object or null of there is no icon with the supplied width.
   */
  async createIconURL(iconRecord) {
    let iconData;
    try {
      iconData = await this.#iconCollection.attachments.get(iconRecord);
    } catch (ex) {
      console.error(ex);
    }
    if (!iconData) {
      console.warn("Unable to find the attachment for", iconRecord.id);
      // Queue an update in case we haven't downloaded it yet.
      this.#pendingUpdatesMap.set(iconRecord.id, iconRecord);
      this.#maybeQueueIdle();
      return null;
    }

    if (iconData.record.last_modified != iconRecord.last_modified) {
      // The icon we have stored is out of date, queue an update so that we'll
      // download the new icon.
      this.#pendingUpdatesMap.set(iconRecord.id, iconRecord);
      this.#maybeQueueIdle();
    }
    return URL.createObjectURL(
      new Blob([iconData.buffer], { type: iconRecord.attachment.mimetype })
    );
    return iconRecord.url;
  }

  QueryInterface = ChromeUtils.generateQI(["nsIObserver"]);
@@ -234,27 +216,23 @@ class IconHandler {
   * Obtains the icon list from the remote settings collection.
   */
  async #buildIconMap() {
    let iconList = [];
    try {
      iconList = await this.#iconCollection.get();
      this.#iconMap = new Map(
        Object.entries(
          await (
            await fetch(
              "chrome://global/content/search/base-browser-search-engine-icons.json"
            )
          ).json()
        )
      );
    } catch (ex) {
      console.error(ex);
      this.#iconMap = null;
    }
    if (!iconList.length) {
    if (!this.#iconMap) {
      console.error("Failed to obtain search engine icon list records");
    }

    this.#iconMap = new Map();
    for (let record of iconList) {
      let keys = new Set(record.engineIdentifiers.map(this.getKey));
      for (let key of keys) {
        if (this.#iconMap.has(key)) {
          this.#iconMap.get(key).push(record);
        } else {
          this.#iconMap.set(key, [record]);
        }
      }
    }
  }

  /**
+22 −49
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 * } from "../uniffi-bindgen-gecko-js/components/generated/RustSearch.sys.mjs";
 */

import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";

const lazy = XPCOMUtils.declareLazy({
@@ -91,42 +92,19 @@ export class SearchEngineSelector {
      return this.#getConfigurationPromise;
    }

    this.#getConfigurationPromise = Promise.all([
      this.#getConfiguration(),
      this.#getConfigurationOverrides(),
    ]);
    let remoteSettingsData = await this.#getConfigurationPromise;
    this.#configuration = remoteSettingsData[0];
    this.#getConfigurationPromise = null;

    if (!this.#configuration?.length) {
      throw Components.Exception(
        "Failed to get engine data from Remote Settings",
        Cr.NS_ERROR_UNEXPECTED
      );
    }

    /**
     * Records whether the listeners have been added or not.
     */
    if (!this.#listenerAdded) {
      this.#remoteConfig.on("sync", this.#boundOnConfigurationUpdated);
      this.#remoteConfigOverrides.on(
        "sync",
        this.#boundOnConfigurationOverridesUpdated
      );
      /**
       * Records whether the listeners have been added or not.
       */
      this.#listenerAdded = true;
    }
    let { promise, resolve } = Promise.withResolvers();
    this.#getConfigurationPromise = promise;
    this.#configuration = await (
      await fetch(
        "chrome://global/content/search/base-browser-search-engines.json"
      )
    ).json();
    resolve(this.#configuration);

    this.#selector.setSearchConfig(
      JSON.stringify({ data: this.#configuration })
    );
    this.#selector.setConfigOverrides(
      JSON.stringify({ data: remoteSettingsData[1] })
    );
    this.#selector.setConfigOverrides(JSON.stringify({ data: [] }));

    return this.#configuration;
  }
@@ -369,6 +347,12 @@ export class SearchEngineSelector {
   *   The new configuration object
   */
  _onConfigurationUpdated({ data: { current } }) {
    // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do
    // not want them to interfere in any way.
    if (AppConstants.BASE_BROWSER_VERSION) {
      return;
    }

    this.#configuration = current;

    this.#selector.setSearchConfig(
@@ -396,6 +380,12 @@ export class SearchEngineSelector {
   *   The new configuration object
   */
  _onConfigurationOverridesUpdated({ data: { current } }) {
    // tor-browser#43525: Even though RemoteSettings are a no-op for us, we do
    // not want them to interfere in any way.
    if (AppConstants.BASE_BROWSER_VERSION) {
      return;
    }

    this.#selector.setConfigOverrides(JSON.stringify({ data: current }));

    lazy.logConsole.debug("Search configuration overrides updated remotely");
@@ -404,23 +394,6 @@ export class SearchEngineSelector {
    }
  }

  /**
   * Obtains the configuration overrides from remote settings.
   *
   * @returns {Promise<object[]>}
   *   An array of objects in the database, or an empty array if none
   *   could be obtained.
   */
  async #getConfigurationOverrides() {
    let result = [];
    try {
      result = await this.#remoteConfigOverrides.get();
    } catch (ex) {
      // This data is remote only, so we just return an empty array if it fails.
    }
    return result;
  }

  /**
   * @type {InstanceType<typeof lazy.SearchEngineSelector>?}
   */
+15 −0
Original line number Diff line number Diff line
{
  "ddg": [
    { "url": "chrome://global/content/search/duckduckgo.ico", "imageSize": 32 }
  ],
  "startpage": [
    {
      "url": "chrome://global/content/search/startpage-16.png",
      "imageSize": 16
    },
    {
      "url": "chrome://global/content/search/startpage-32.png",
      "imageSize": 32
    }
  ]
}
+43 −0
Original line number Diff line number Diff line
[
  {
    "base": {
      "aliases": ["duckduckgo", "ddg"],
      "classification": "general",
      "name": "DuckDuckGo",
      "urls": {
        "search": {
          "base": "https://duckduckgo.com/",
          "params": [],
          "searchTermParamName": "q"
        }
      }
    },
    "id": "04e99a38-13ee-47d8-8aa4-64482b3dea99",
    "identifier": "ddg",
    "recordType": "engine",
    "variants": [{ "environment": { "allRegionsAndLocales": true } }]
  },
  {
    "base": {
      "aliases": ["startpage", "sp"],
      "classification": "general",
      "name": "Startpage",
      "urls": {
        "search": {
          "base": "https://www.startpage.com/sp/search",
          "params": [],
          "searchTermParamName": "q"
        }
      }
    },
    "id": "927bbd9f-b2f3-48b4-8974-1c1148028f4d",
    "identifier": "startpage",
    "recordType": "engine",
    "variants": [{ "environment": { "allRegionsAndLocales": true } }]
  },
  {
    "recordType": "defaultEngines",
    "globalDefault": "ddg",
    "globalDefaultPrivate": "ddg"
  }
]
+2.73 KiB
Loading image diff...
Loading