Bug 1040931 - Add extensionID parameter to addEngineWithDetails r=gavin
authorTim Taubert <ttaubert@mozilla.com>
Wed, 27 Aug 2014 16:38:20 +0200
changeset 202025 4ed05a6cb24a999567418af4f35d57eff341e4da
parent 202024 f3d15f941c583374affebb74f64b1b020b445892
child 202026 8591ca11b95071b6d22316ad22ffc7d4ce599724
push id48309
push userkwierso@gmail.com
push dateWed, 27 Aug 2014 23:59:44 +0000
treeherdermozilla-inbound@a531fd3f3ab7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgavin
bugs1040931
milestone34.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 1040931 - Add extensionID parameter to addEngineWithDetails r=gavin
netwerk/base/public/nsIBrowserSearchService.idl
toolkit/components/search/nsSearchService.js
toolkit/components/search/tests/xpcshell/data/search.json
toolkit/components/search/tests/xpcshell/test_json_cache.js
--- a/netwerk/base/public/nsIBrowserSearchService.idl
+++ b/netwerk/base/public/nsIBrowserSearchService.idl
@@ -234,17 +234,17 @@ interface nsIBrowserSearchInitObserver :
   /**
    * Called once initialization of the browser search service is complete.
    *
    * @param aStatus The status of that service.
    */
   void onInitComplete(in nsresult aStatus);
 };
 
-[scriptable, uuid(939d74a4-5b01-463c-80c7-4301f0c0f9ef)]
+[scriptable, uuid(4a4ce87d-7cb9-4975-a267-345f6a49bb8f)]
 interface nsIBrowserSearchService : nsISupports
 {
   /**
    * Start asynchronous initialization.
    *
    * The callback is triggered once initialization is complete, which may be
    * immediately, if initialization has already been completed by some previous
    * call to this method. The callback is always invoked asynchronously.
@@ -322,23 +322,27 @@ interface nsIBrowserSearchService : nsIS
    *
    * @param method
    *        The HTTP request method used when submitting a search query.
    *        Must be a case insensitive value of either "get" or "post".
    *
    * @param url
    *        The URL to which search queries should be sent.
    *        Must not be null.
+   *
+   * @param extensionID [optional]
+   *        Optional: The correct extensionID if called by an add-on.
    */
   void addEngineWithDetails(in AString name,
                             in AString iconURL,
                             in AString alias,
                             in AString description,
                             in AString method,
-                            in AString url);
+                            in AString url,
+                            [optional] in AString extensionID);
 
   /**
    * Un-hides all engines installed in the directory corresponding to
    * the directory service's NS_APP_SEARCH_DIR key. (i.e. the set of
    * engines returned by getDefaultEngines)
    */
   void restoreDefaultEngines();
 
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -1122,16 +1122,18 @@ Engine.prototype = {
   // The number of days between update checks for new versions
   _updateInterval: null,
   // The url to check at for a new update
   _updateURL: null,
   // The url to check for a new icon
   _iconUpdateURL: null,
   /* Deferred serialization task. */
   _lazySerializeTask: null,
+  /* The extension ID if added by an extension. */
+  _extensionID: null,
 
   /**
    * Retrieves the data from the engine's file. If the engine's dataType is
    * XML, the document element is placed in the engine's data field. For text
    * engines, the data is just read directly from file and placed as an array
    * of lines in the engine's data field.
    */
   _initFromFile: function SRCH_ENG_initFromFile() {
@@ -1668,27 +1670,28 @@ Engine.prototype = {
     this._data = null;
   },
 
   /**
    * Initialize this Engine object from a collection of metadata.
    */
   _initFromMetadata: function SRCH_ENG_initMetaData(aName, aIconURL, aAlias,
                                                     aDescription, aMethod,
-                                                    aTemplate) {
+                                                    aTemplate, aExtensionID) {
     ENSURE_WARN(!this._readOnly,
                 "Can't call _initFromMetaData on a readonly engine!",
                 Cr.NS_ERROR_FAILURE);
 
     this._urls.push(new EngineURL(URLTYPE_SEARCH_HTML, aMethod, aTemplate));
 
     this._name = aName;
     this.alias = aAlias;
     this._description = aDescription;
     this._setIcon(aIconURL, true);
+    this._extensionID = aExtensionID;
 
     this._serializeToFile();
   },
 
   /**
    * Extracts data from an OpenSearch URL element and creates an EngineURL
    * object which is then added to the engine's list of URLs.
    *
@@ -1856,16 +1859,19 @@ Engine.prototype = {
           this._updateURL = child.textContent;
           break;
         case "UpdateInterval":
           this._updateInterval = parseInt(child.textContent);
           break;
         case "IconUpdateUrl":
           this._iconUpdateURL = child.textContent;
           break;
+        case "ExtensionID":
+          this._extensionID = child.textContent;
+          breakk;
       }
     }
     if (!this.name || (this._urls.length == 0))
       FAIL("_parseAsOpenSearch: No name, or missing URL!", Cr.NS_ERROR_FAILURE);
     if (!this.supportsResponseType(URLTYPE_SEARCH_HTML))
       FAIL("_parseAsOpenSearch: No text/html result type!", Cr.NS_ERROR_FAILURE);
   },
 
@@ -2200,16 +2206,19 @@ Engine.prototype = {
     this._updateURL = aJson._updateURL || null;
     this._iconUpdateURL = aJson._iconUpdateURL || null;
     if (aJson._readOnly == undefined)
       this._readOnly = true;
     else
       this._readOnly = false;
     this._iconURI = makeURI(aJson._iconURL);
     this._iconMapObj = aJson._iconMapObj;
+    if (aJson.extensionID) {
+      this._extensionID = aJson.extensionID;
+    }
     for (let i = 0; i < aJson._urls.length; ++i) {
       let url = aJson._urls[i];
       let engineURL = new EngineURL(url.type || URLTYPE_SEARCH_HTML,
                                     url.method || "GET", url.template,
                                     url.resultDomain);
       engineURL._initWithJSON(url, this);
       this._urls.push(engineURL);
     }
@@ -2251,16 +2260,19 @@ Engine.prototype = {
     if (this.type != SEARCH_TYPE_MOZSEARCH || !aFilter)
       json.type = this.type;
     if (this.queryCharset != DEFAULT_QUERY_CHARSET || !aFilter)
       json.queryCharset = this.queryCharset;
     if (this._dataType != SEARCH_DATA_XML || !aFilter)
       json._dataType = this._dataType;
     if (!this._readOnly || !aFilter)
       json._readOnly = this._readOnly;
+    if (this._extensionID) {
+      json.extensionID = this._extensionID;
+    }
 
     return json;
   },
 
   /**
    * Returns an XML document object containing the search plugin information,
    * which can later be used to reload the engine.
    */
@@ -2296,16 +2308,20 @@ Engine.prototype = {
       }
     }
 
     appendTextNode(MOZSEARCH_NS_10, "UpdateInterval", this._updateInterval);
     appendTextNode(MOZSEARCH_NS_10, "UpdateUrl", this._updateURL);
     appendTextNode(MOZSEARCH_NS_10, "IconUpdateUrl", this._iconUpdateURL);
     appendTextNode(MOZSEARCH_NS_10, "SearchForm", this._searchForm);
 
+    if (this._extensionID) {
+      appendTextNode(MOZSEARCH_NS_10, "ExtensionID", this._extensionID);
+    }
+
     for (var i = 0; i < this._urls.length; ++i)
       this._urls[i]._serializeToElement(doc, docElem);
     docElem.appendChild(doc.createTextNode("\n"));
 
     return doc;
   },
 
   get lazySerializeTask() {
@@ -3948,30 +3964,30 @@ SearchService.prototype = {
       if (engine && engine.alias == aAlias)
         return engine;
     }
     return null;
   },
 
   addEngineWithDetails: function SRCH_SVC_addEWD(aName, aIconURL, aAlias,
                                                  aDescription, aMethod,
-                                                 aTemplate) {
+                                                 aTemplate, aExtensionID) {
     this._ensureInitialized();
     if (!aName)
       FAIL("Invalid name passed to addEngineWithDetails!");
     if (!aMethod)
       FAIL("Invalid method passed to addEngineWithDetails!");
     if (!aTemplate)
       FAIL("Invalid template passed to addEngineWithDetails!");
     if (this._engines[aName])
       FAIL("An engine with that name already exists!", Cr.NS_ERROR_FILE_ALREADY_EXISTS);
 
     var engine = new Engine(getSanitizedFile(aName), SEARCH_DATA_XML, false);
     engine._initFromMetadata(aName, aIconURL, aAlias, aDescription,
-                             aMethod, aTemplate);
+                             aMethod, aTemplate, aExtensionID);
     this._addEngineToStore(engine);
   },
 
   addEngine: function SRCH_SVC_addEngine(aEngineURL, aDataType, aIconURL,
                                          aConfirm, aCallback) {
     LOG("addEngine: Adding \"" + aEngineURL + "\".");
     this._ensureInitialized();
     try {
--- a/toolkit/components/search/tests/xpcshell/data/search.json
+++ b/toolkit/components/search/tests/xpcshell/data/search.json
@@ -6,16 +6,17 @@
     "[profile]/searchplugins": {
       "lastModifiedTime": 1333761316000,
       "engines": [
         {
           "_id": "[app]/test-search-engine.xml",
           "_name": "Test search engine",
           "_hidden": false,
           "description": "A test search engine (based on Google search)",
+          "extensionID": "test-addon-id@mozilla.org",
           "__searchForm": "http://www.google.com/",
           "_iconURL": "data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA",
           "_urls": [
             {
               "template": "http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}&q={searchTerms}",
               "rels": [
               ],
               "type": "application/x-suggestions+json",
--- a/toolkit/components/search/tests/xpcshell/test_json_cache.js
+++ b/toolkit/components/search/tests/xpcshell/test_json_cache.js
@@ -178,16 +178,17 @@ add_test(function test_cache_write() {
 let EXPECTED_ENGINE = {
   engine: {
     name: "Test search engine",
     alias: null,
     description: "A test search engine (based on Google search)",
     searchForm: "http://www.google.com/",
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     wrappedJSObject: {
+      _extensionID: "test-addon-id@mozilla.org",
       "_iconURL": "data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA",
       _urls : [
         {
           type: "application/x-suggestions+json",
           method: "GET",
           template: "http://suggestqueries.google.com/complete/search?output=firefox&client=firefox" +
                       "&hl={moz:locale}&q={searchTerms}",
           params: "",