Bug 1374695 - Add extensionID to addEngine API. r?florian draft
authorMichael Kaply <mozilla@kaply.com>
Mon, 14 Aug 2017 15:51:12 -0500
changeset 647695 552f19544ac91f73260761c9a487e23aece87fc6
parent 647460 6ebc251bd288c268b020815025b05854ccde5c08
child 726607 9db90c3bdf71f0226d35ea183e6de51f5af472c7
push id74513
push usermozilla@kaply.com
push dateWed, 16 Aug 2017 20:26:26 +0000
reviewersflorian
bugs1374695
milestone57.0a1
Bug 1374695 - Add extensionID to addEngine API. r?florian MozReview-Commit-ID: 5hxzvCXhMxi
netwerk/base/nsIBrowserSearchService.idl
toolkit/components/search/nsSearchService.js
toolkit/components/search/tests/xpcshell/test_addEngineWithExtensionID.js
toolkit/components/telemetry/docs/data/environment.rst
--- a/netwerk/base/nsIBrowserSearchService.idl
+++ b/netwerk/base/nsIBrowserSearchService.idl
@@ -309,21 +309,25 @@ interface nsIBrowserSearchService : nsIS
    *        value is false, the engine will be added to the list upon successful
    *        load, but it will not be selected as the current engine.
    *
    * @param callback
    *        A nsISearchInstallCallback that will be notified when the
    *        addition is complete, or if the addition fails. It will not be
    *        called if addEngine throws an exception.
    *
+   * @param extensionID [optional]
+   *        Optional: The correct extensionID if called by an add-on.
+   *
    * @throws NS_ERROR_FAILURE if the description file cannot be successfully
    *         loaded.
    */
   void addEngine(in AString engineURL, in long dataType, in AString iconURL,
-                 in boolean confirm, [optional] in nsISearchInstallCallback callback);
+                 in boolean confirm, [optional] in nsISearchInstallCallback callback,
+                 [optional] in AString extensionID);
 
   /**
    * Adds a new search engine, without asking the user for confirmation and
    * without starting to use it right away.
    *
    * @param name
    *        The search engine's name. Must be unique. Must not be null.
    *
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -1619,16 +1619,19 @@ Engine.prototype = {
           onError();
           return;
         }
         aEngine._useNow = confirmation.useNow;
       }
 
       aEngine._shortName = sanitizeName(aEngine.name);
       aEngine._loadPath = aEngine.getAnonymizedLoadPath(null, aEngine._uri);
+      if (aEngine._extensionID) {
+        aEngine._loadPath += ":" + aEngine._extensionID;
+      }
       aEngine.setAttr("loadPathHash", getVerificationHash(aEngine._loadPath));
     }
 
     // Notify the search service of the successful load. It will deal with
     // updates by checking aEngine._engineToUpdate.
     notifyAction(aEngine, SEARCH_ENGINE_LOADED);
 
     // Notify the callback if needed
@@ -4036,17 +4039,17 @@ SearchService.prototype = {
     engine._loadPath = "[other]addEngineWithDetails";
     if (params.extensionID) {
       engine._loadPath += ":" + params.extensionID;
     }
     this._addEngineToStore(engine);
   },
 
   addEngine: function SRCH_SVC_addEngine(aEngineURL, aDataType, aIconURL,
-                                         aConfirm, aCallback) {
+                                         aConfirm, aCallback, aExtensionID) {
     LOG("addEngine: Adding \"" + aEngineURL + "\".");
     this._ensureInitialized();
     try {
       var uri = makeURI(aEngineURL);
       var engine = new Engine(uri, false);
       if (aCallback) {
         engine._installCallback = function(errorCode) {
           try {
@@ -4065,16 +4068,19 @@ SearchService.prototype = {
     } catch (ex) {
       // Drop the reference to the callback, if set
       if (engine)
         engine._installCallback = null;
       FAIL("addEngine: Error adding engine:\n" + ex, Cr.NS_ERROR_FAILURE);
     }
     engine._setIcon(aIconURL, false);
     engine._confirm = aConfirm;
+    if (aExtensionID) {
+      engine._extensionID = aExtensionID;
+    }
   },
 
   removeEngine: function SRCH_SVC_removeEngine(aEngine) {
     this._ensureInitialized();
     if (!aEngine)
       FAIL("no engine passed to removeEngine!");
 
     var engineToRemove = null;
--- a/toolkit/components/search/tests/xpcshell/test_addEngineWithExtensionID.js
+++ b/toolkit/components/search/tests/xpcshell/test_addEngineWithExtensionID.js
@@ -1,25 +1,50 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 const kSearchEngineID = "addEngineWithDetails_test_engine";
 const kSearchEngineURL = "http://example.com/?search={searchTerms}";
 const kSearchTerm = "foo";
-const kExtensionID = "extension@mozilla.com";
+const kExtensionID1 = "extension1@mozilla.com";
+const kExtensionID2 = "extension2@mozilla.com";
+const kExtension2LoadPath = "[http]localhost/test-search-engine.xml:extension2@mozilla.com";
 
-add_task(async function test_addEngineWithExtensionID() {
+add_task(async function test_addEngineWithDetailsWithExtensionID() {
   do_check_false(Services.search.isInitialized);
 
   await asyncInit();
 
   Services.search.addEngineWithDetails(kSearchEngineID, "", "", "", "get",
-                                       kSearchEngineURL, kExtensionID);
+                                       kSearchEngineURL, kExtensionID1);
 
   let engine = Services.search.getEngineByName(kSearchEngineID);
   do_check_neq(engine, null);
 
-  let engines = Services.search.getEnginesByExtensionID(kExtensionID);
+  let engines = Services.search.getEnginesByExtensionID(kExtensionID1);
   do_check_eq(engines.length, 1);
   do_check_eq(engines[0], engine);
 });
+
+add_test(function test_addEngineWithExtensionID() {
+  let searchCallback = {
+    onSuccess(engine) {
+      let engines = Services.search.getEnginesByExtensionID(kExtensionID2);
+      do_check_eq(engines.length, 1);
+      do_check_eq(engines[0], engine);
+      do_check_eq(engine.wrappedJSObject._loadPath, kExtension2LoadPath);
+      run_next_test();
+    },
+    onError(errorCode) {
+      do_throw("search callback returned error: " + errorCode);
+    }
+  }
+  Services.search.addEngine(gDataUrl + "engine.xml", null,
+                            null, false, searchCallback, kExtensionID2);
+});
+
+function run_test() {
+  useHttpServer();
+
+  run_next_test();
+}
--- a/toolkit/components/telemetry/docs/data/environment.rst
+++ b/toolkit/components/telemetry/docs/data/environment.rst
@@ -304,16 +304,20 @@ The object contains:
   engine is currently set as the default.
 
 - a ``loadPath`` property: an anonymized path of the engine xml file, e.g.
   jar:[app]/omni.ja!browser/engine.xml
   (where 'browser' is the name of the chrome package, not a folder)
   [profile]/searchplugins/engine.xml
   [distribution]/searchplugins/common/engine.xml
   [other]/engine.xml
+  [other]/addEngineWithDetails
+  [other]/addEngineWithDetails:extensionID
+  [http/https]example.com/engine-name.xml
+  [http/https]example.com/engine-name.xml:extensionID
 
 - an ``origin`` property: the value will be ``default`` for engines that are built-in or from distribution partners, ``verified`` for user-installed engines with valid verification hashes, ``unverified`` for non-default engines without verification hash, and ``invalid`` for engines with broken verification hashes.
 
 - a ``submissionURL`` property with the HTTP url we would use to search.
   For privacy, we don't record this for user-installed engines.
 
 ``loadPath`` and ``submissionURL`` are not present if ``name`` is ``NONE``.