Bug 1496075 - Part 1: Extensions changes to support search extensions. r=mixedpuppy,robwu
authorDale Harvey <dale@arandomurl.com>
Thu, 11 Apr 2019 21:30:47 +0000
changeset 469099 7efb082cc25d1a58fe343055982b1459b2f9e1ee
parent 469098 041d3ca2a427f411d361ce55d6398bf749944cae
child 469100 e07b4ceea0777d40402f2af1b601b2705deb2a78
push id35856
push usercsabou@mozilla.com
push dateFri, 12 Apr 2019 03:19:48 +0000
treeherdermozilla-central@940684cd1065 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy, robwu
bugs1496075
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1496075 - Part 1: Extensions changes to support search extensions. r=mixedpuppy,robwu Differential Revision: https://phabricator.services.mozilla.com/D25244
browser/base/content/test/webextensions/head.js
browser/components/extensions/parent/ext-chrome-settings-overrides.js
browser/components/extensions/schemas/chrome_settings_overrides.json
browser/components/extensions/test/xpcshell/test_ext_settings_overrides_search.js
browser/components/extensions/test/xpcshell/test_ext_settings_overrides_shutdown.js
--- a/browser/base/content/test/webextensions/head.js
+++ b/browser/base/content/test/webextensions/head.js
@@ -535,17 +535,20 @@ add_task(async function() {
 
   registerCleanupFunction(async function() {
     if (testCleanup) {
       await testCleanup();
       testCleanup = null;
     }
 
     for (let addon of await AddonManager.getAllAddons()) {
-      if (!existingAddons.has(addon.id)) {
+      // Builtin search extensions may have been installed by SearchService
+      // during the test run, ignore those.
+      if (!existingAddons.has(addon.id) &&
+          !(addon.isBuiltin && addon.id.endsWith("@search.mozilla.org"))) {
         ok(false, `Addon ${addon.id} was left installed at the end of the test`);
         await addon.uninstall();
       }
     }
   });
 });
 
 let collectedTelemetry = [];
--- a/browser/components/extensions/parent/ext-chrome-settings-overrides.js
+++ b/browser/components/extensions/parent/ext-chrome-settings-overrides.js
@@ -119,23 +119,27 @@ this.chrome_settings_overrides = class e
 
   static async removeEngine(id) {
     await ExtensionSettingsStore.initialize();
     let item = await ExtensionSettingsStore.getSetting(
       DEFAULT_SEARCH_STORE_TYPE, ENGINE_ADDED_SETTING_NAME, id);
     if (item) {
       ExtensionSettingsStore.removeSetting(
         id, DEFAULT_SEARCH_STORE_TYPE, ENGINE_ADDED_SETTING_NAME);
-      await searchInitialized;
-      let engine = Services.search.getEngineByName(item.value);
-      try {
-        await Services.search.removeEngine(engine);
-      } catch (e) {
-        Cu.reportError(e);
-      }
+    }
+    // We can call removeEngine in nsSearchService startup, if so we dont
+    // need to reforward the call, just disable the web extension.
+    if (!Services.search.isInitialized) {
+      return;
+    }
+
+    try {
+      await Services.search.removeWebExtensionEngine(id);
+    } catch (e) {
+      Cu.reportError(e);
     }
   }
 
   static removeSearchSettings(id) {
     return Promise.all([
       this.processDefaultSearchSetting("removeSetting", id),
       this.removeEngine(id),
     ]);
@@ -239,34 +243,35 @@ this.chrome_settings_overrides = class e
         });
 
       // Save the promise so we can await at onUninstall.
       pendingSearchSetupTasks.set(extension.id, searchStartupPromise);
     }
   }
 
   async processSearchProviderManifestEntry() {
-    await searchInitialized;
-
     let {extension} = this;
-    if (!extension) {
-      Cu.reportError(`Extension shut down before search provider was registered`);
-      return;
+    let {manifest} = extension;
+    let searchProvider = manifest.chrome_settings_overrides.search_provider;
+    if (searchProvider.is_default) {
+      await searchInitialized;
+      if (!this.extension) {
+        Cu.reportError(`Extension shut down before search provider was registered`);
+        return;
+      }
     }
     extension.callOnClose({
       close: () => {
         if (extension.shutdownReason == "ADDON_DISABLE") {
           chrome_settings_overrides.processDefaultSearchSetting("disable", extension.id);
           chrome_settings_overrides.removeEngine(extension.id);
         }
       },
     });
 
-    let {manifest} = extension;
-    let searchProvider = manifest.chrome_settings_overrides.search_provider;
     let engineName = searchProvider.name.trim();
     if (searchProvider.is_default) {
       let engine = Services.search.getEngineByName(engineName);
       let defaultEngines = await Services.search.getDefaultEngines();
       if (engine && defaultEngines.some(defaultEngine => defaultEngine.name == engineName)) {
         // Needs to be called every time to handle reenabling, but
         // only sets default for install or enable.
         await this.setDefault(engineName);
@@ -339,24 +344,24 @@ this.chrome_settings_overrides = class e
         // There can be only one engine right now
         isCurrent = (await Services.search.getDefault()).name == firstEngineName;
         // Get position of engine and store it
         index = (await Services.search.getEngines()).map(engine => engine.name).indexOf(firstEngineName);
         await Services.search.removeEngine(firstEngine);
       }
     }
     try {
-      await Services.search.addEnginesFromExtension(extension);
-      // Bug 1488516.  Preparing to support multiple engines per extension so
-      // multiple locales can be loaded.
-      let engines = await Services.search.getEnginesByExtensionID(extension.id);
-      await ExtensionSettingsStore.addSetting(
-        extension.id, DEFAULT_SEARCH_STORE_TYPE, ENGINE_ADDED_SETTING_NAME,
-        engines[0].name);
+      let engines = await Services.search.addEnginesFromExtension(extension);
+      if (engines.length > 0) {
+        await ExtensionSettingsStore.addSetting(
+          extension.id, DEFAULT_SEARCH_STORE_TYPE, ENGINE_ADDED_SETTING_NAME,
+          engines[0].name);
+      }
       if (extension.startupReason === "ADDON_UPGRADE") {
+        let engines = await Services.search.getEnginesByExtensionID(extension.id);
         let engine = Services.search.getEngineByName(engines[0].name);
         if (isCurrent) {
           await Services.search.setDefault(engine);
         }
         if (index != -1) {
           await Services.search.moveEngine(engine, index);
         }
       }
--- a/browser/components/extensions/schemas/chrome_settings_overrides.json
+++ b/browser/components/extensions/schemas/chrome_settings_overrides.json
@@ -40,39 +40,51 @@
                     "type": "string",
                     "optional": true,
                     "format": "url",
                     "preprocess": "localize"
                   },
                   "suggest_url": {
                     "type": "string",
                     "optional": true,
-                    "format": "url",
+                    "pattern": "^https://.*$|^$",
                     "preprocess": "localize"
                   },
                   "instant_url": {
                     "type": "string",
                     "optional": true,
                     "format": "url",
                     "preprocess": "localize",
                     "deprecated": "Unsupported on Firefox at this time."
                   },
                   "image_url": {
                     "type": "string",
                     "optional": true,
                     "format": "url",
                     "preprocess": "localize",
                     "deprecated": "Unsupported on Firefox at this time."
                   },
+                  "search_url_get_params": {
+                    "type": "string",
+                    "optional": true,
+                    "preprocess": "localize",
+                    "description": "GET parameters to the search_url as a query string."
+                  },
                   "search_url_post_params": {
                     "type": "string",
                     "optional": true,
                     "preprocess": "localize",
                     "description": "POST parameters to the search_url as a query string."
                   },
+                  "suggest_url_get_params": {
+                    "type": "string",
+                    "optional": true,
+                    "preprocess": "localize",
+                    "description": "GET parameters to the suggest_url as a query string."
+                  },
                   "suggest_url_post_params": {
                     "type": "string",
                     "optional": true,
                     "preprocess": "localize",
                     "description": "POST parameters to the suggest_url as a query string."
                   },
                   "instant_url_post_params": {
                     "type": "string",
@@ -81,16 +93,23 @@
                     "deprecated": "Unsupported on Firefox at this time."
                   },
                   "image_url_post_params": {
                     "type": "string",
                     "optional": true,
                     "preprocess": "localize",
                     "deprecated": "Unsupported on Firefox at this time."
                   },
+                  "search_form": {
+                    "type": "string",
+                    "optional": true,
+                    "format": "url",
+                    "pattern": "^https://.*$",
+                    "preprocess": "localize"
+                  },
                   "alternate_urls": {
                     "type": "array",
                     "items": {
                       "type": "string",
                       "format": "url",
                       "preprocess": "localize"
                     },
                     "optional": true,
@@ -136,17 +155,18 @@
                           "type": "string",
                           "optional": true,
                           "enum": ["contextmenu", "searchbar", "homepage", "keyword", "newtab"],
                           "description": "The context that initiates a search, required if condition is \"purpose\"."
                         },
                         "value": {
                           "type": "string",
                           "optional": true,
-                          "description": "A url parameter value."
+                          "description": "A url parameter value.",
+                          "preprocess": "localize"
                         }
                       }
                     },
                     "description": "A list of optional search url parameters. This allows the additon of search url parameters based on how the search is performed in Firefox."
                   }
                 }
               }
             }
--- a/browser/components/extensions/test/xpcshell/test_ext_settings_overrides_search.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_settings_overrides_search.js
@@ -4,17 +4,17 @@
 "use strict";
 
 const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
 const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
 
 let delay = () => new Promise(resolve => setTimeout(resolve, 0));
 
 const kSearchEngineURL = "https://example.com/?search={searchTerms}";
-const kSearchSuggestURL = "http://example.com/?suggest={searchTerms}";
+const kSearchSuggestURL = "https://example.com/?suggest={searchTerms}";
 const kSearchTerm = "foo";
 const kSearchTermIntl = "日";
 const URLTYPE_SUGGEST_JSON = "application/x-suggestions+json";
 
 AddonTestUtils.init(this);
 AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "42", "42");
 
 add_task(async function setup() {
--- a/browser/components/extensions/test/xpcshell/test_ext_settings_overrides_shutdown.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_settings_overrides_shutdown.js
@@ -16,16 +16,17 @@ AddonTestUtils.createAppInfo("xpcshell@t
 add_task(async function shutdown_during_search_provider_startup() {
   await AddonTestUtils.promiseStartupManager();
 
   let extension = ExtensionTestUtils.loadExtension({
     useAddonManager: "permanent",
     manifest: {
       chrome_settings_overrides: {
         search_provider: {
+          is_default: true,
           name: "dummy name",
           search_url: "https://example.com/",
         },
       },
     },
   });
 
   info("Starting up search extension");