forked from mirrors/gecko-dev
		
	This is a rollup of all the patches that have landed on the cedar project branch:891252fdd0Bug 1492475 - Part 1: Migrate most, if not all nsSearchService consumers to use async APIs. r=florian79b2eb2367Bug 1492475 - Part 2: Move nsIBrowserSearchService.idl to toolkit/components/search/nsISearchService.idl and update references. r=floriana947d3cdf0Bug 1492475 - Part 3: The search service init() method should simply return a Promise. r=florianc1e172dfacBug 1492475 - Part 4: Remove the synchronous initialization flow. r=floriancd41189eacBug 1492475 - Part 5: Since async initialization of the search service now is implicit behavior, remove the distinctive verbiage used internally. r=florian2ae7189dfaBug 1492475 - Part 6: Update the cache build task to work with an actual Promise and re-initialize only once at the same time - all to fix race conditions here. r=florianc8ee92973fBug 1492475 - Part 7: Make the region fetch not block the init flow, to ensure it's as fast as possible. r=florianc44e674e16Bug 1492475 - Part 8: Introduce an init flag, which can only be used privately, that allows to explicitly skip waiting for the region check process to complete. r=florian6c79eaf1d3Bug 1492475 - Part 9: Update unit tests to stop using 'currentEngine', in favor of 'defaultEngine'. r=Standard821b3aa17eeBug 1492475 - Part 10: Update unit tests to be fully aware of the new, async signatures of the search service API and remove sync init flow tests. r=mkaply,floriance5ba69019Bug 1492475 - Part 11: Repair incorrect usage of the `identifier` property of nsISearchEngine instances. r=florianfd177a7994Bug 1518543 - Fix up the Android (Fennec) nsISearchService shim to work with the new asynchronous API. r=florian3653d8ee22Bug 1523708 - Change the search service interaction in the show-heartbeat action to use the new async API. r=florian Differential Revision: https://phabricator.services.mozilla.com/D18355 --HG-- rename : netwerk/base/nsIBrowserSearchService.idl => toolkit/components/search/nsISearchService.idl extra : moz-landing-system : lando
		
			
				
	
	
		
			186 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* eslint-env mozilla/frame-script */
 | 
						|
 | 
						|
XPCOMUtils.defineLazyModuleGetters(this, {
 | 
						|
  FormHistory: "resource://gre/modules/FormHistory.jsm",
 | 
						|
});
 | 
						|
 | 
						|
function getSecurityInfo(securityInfoAsString) {
 | 
						|
  const serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
 | 
						|
                       .getService(Ci.nsISerializationHelper);
 | 
						|
  let securityInfo = serhelper.deserializeObject(securityInfoAsString);
 | 
						|
  securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
 | 
						|
  return securityInfo;
 | 
						|
}
 | 
						|
 | 
						|
function getCertChain(securityInfoAsString) {
 | 
						|
  let certChain = "";
 | 
						|
  let securityInfo = getSecurityInfo(securityInfoAsString);
 | 
						|
  for (let cert of securityInfo.failedCertChain.getEnumerator()) {
 | 
						|
    certChain += getPEMString(cert);
 | 
						|
  }
 | 
						|
  return certChain;
 | 
						|
}
 | 
						|
 | 
						|
function getDERString(cert) {
 | 
						|
  var length = {};
 | 
						|
  var derArray = cert.getRawDER(length);
 | 
						|
  var derString = "";
 | 
						|
  for (var i = 0; i < derArray.length; i++) {
 | 
						|
    derString += String.fromCharCode(derArray[i]);
 | 
						|
  }
 | 
						|
  return derString;
 | 
						|
}
 | 
						|
 | 
						|
function getPEMString(cert) {
 | 
						|
  var derb64 = btoa(getDERString(cert));
 | 
						|
  // Wrap the Base64 string into lines of 64 characters,
 | 
						|
  // with CRLF line breaks (as specified in RFC 1421).
 | 
						|
  var wrapped = derb64.replace(/(\S{64}(?!$))/g, "$1\r\n");
 | 
						|
  return "-----BEGIN CERTIFICATE-----\r\n"
 | 
						|
         + wrapped
 | 
						|
         + "\r\n-----END CERTIFICATE-----\r\n";
 | 
						|
}
 | 
						|
 | 
						|
function injectErrorPageFrame(tab, src) {
 | 
						|
  return ContentTask.spawn(tab.linkedBrowser, {frameSrc: src}, async function({frameSrc}) {
 | 
						|
    let loaded = ContentTaskUtils.waitForEvent(content.wrappedJSObject, "DOMFrameContentLoaded");
 | 
						|
    let iframe = content.document.createElement("iframe");
 | 
						|
    iframe.src = frameSrc;
 | 
						|
    content.document.body.appendChild(iframe);
 | 
						|
    await loaded;
 | 
						|
    // We will have race conditions when accessing the frame content after setting a src,
 | 
						|
    // so we can't wait for AboutNetErrorLoad. Let's wait for the certerror class to
 | 
						|
    // appear instead (which should happen at the same time as AboutNetErrorLoad).
 | 
						|
    await ContentTaskUtils.waitForCondition(() =>
 | 
						|
      iframe.contentDocument.body.classList.contains("certerror"));
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
async function openErrorPage(src, useFrame) {
 | 
						|
  let dummyPage = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "dummy_page.html";
 | 
						|
 | 
						|
  let tab;
 | 
						|
  if (useFrame) {
 | 
						|
    info("Loading cert error page in an iframe");
 | 
						|
    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, dummyPage);
 | 
						|
    await injectErrorPageFrame(tab, src);
 | 
						|
  } else {
 | 
						|
    let certErrorLoaded;
 | 
						|
    tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
 | 
						|
      gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
 | 
						|
      let browser = gBrowser.selectedBrowser;
 | 
						|
      certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
 | 
						|
    }, false);
 | 
						|
    info("Loading and waiting for the cert error");
 | 
						|
    await certErrorLoaded;
 | 
						|
  }
 | 
						|
 | 
						|
  return tab;
 | 
						|
}
 | 
						|
 | 
						|
function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
 | 
						|
  retryTimes = typeof retryTimes !== "undefined" ? retryTimes : 30;
 | 
						|
  var tries = 0;
 | 
						|
  var interval = setInterval(function() {
 | 
						|
    if (tries >= retryTimes) {
 | 
						|
      ok(false, errorMsg);
 | 
						|
      moveOn();
 | 
						|
    }
 | 
						|
    var conditionPassed;
 | 
						|
    try {
 | 
						|
      conditionPassed = condition();
 | 
						|
    } catch (e) {
 | 
						|
      ok(false, e + "\n" + e.stack);
 | 
						|
      conditionPassed = false;
 | 
						|
    }
 | 
						|
    if (conditionPassed) {
 | 
						|
      moveOn();
 | 
						|
    }
 | 
						|
    tries++;
 | 
						|
  }, 100);
 | 
						|
  var moveOn = function() { clearInterval(interval); nextTest(); };
 | 
						|
}
 | 
						|
 | 
						|
function whenTabLoaded(aTab, aCallback) {
 | 
						|
  promiseTabLoadEvent(aTab).then(aCallback);
 | 
						|
}
 | 
						|
 | 
						|
function promiseTabLoaded(aTab) {
 | 
						|
  return new Promise(resolve => {
 | 
						|
    whenTabLoaded(aTab, resolve);
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Waits for a load (or custom) event to finish in a given tab. If provided
 | 
						|
 * load an uri into the tab.
 | 
						|
 *
 | 
						|
 * @param tab
 | 
						|
 *        The tab to load into.
 | 
						|
 * @param [optional] url
 | 
						|
 *        The url to load, or the current url.
 | 
						|
 * @return {Promise} resolved when the event is handled.
 | 
						|
 * @resolves to the received event
 | 
						|
 * @rejects if a valid load event is not received within a meaningful interval
 | 
						|
 */
 | 
						|
function promiseTabLoadEvent(tab, url) {
 | 
						|
  info("Wait tab event: load");
 | 
						|
 | 
						|
  function handle(loadedUrl) {
 | 
						|
    if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
 | 
						|
      info(`Skipping spurious load event for ${loadedUrl}`);
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    info("Tab event received: load");
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
 | 
						|
 | 
						|
  if (url)
 | 
						|
    BrowserTestUtils.loadURI(tab.linkedBrowser, url);
 | 
						|
 | 
						|
  return loaded;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Wait for the search engine to change.
 | 
						|
 */
 | 
						|
function promiseContentSearchChange(browser, newEngineName) {
 | 
						|
  return ContentTask.spawn(browser, { newEngineName }, async function(args) {
 | 
						|
    return new Promise(resolve => {
 | 
						|
      content.addEventListener("ContentSearchService", function listener(aEvent) {
 | 
						|
        if (aEvent.detail.type == "CurrentState" &&
 | 
						|
            content.wrappedJSObject.gContentSearchController.defaultEngine.name == args.newEngineName) {
 | 
						|
          content.removeEventListener("ContentSearchService", listener);
 | 
						|
          resolve();
 | 
						|
        }
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Wait for the search engine to be added.
 | 
						|
 */
 | 
						|
async function promiseNewEngine(basename) {
 | 
						|
  info("Waiting for engine to be added: " + basename);
 | 
						|
  let url = getRootDirectory(gTestPath) + basename;
 | 
						|
  let engine;
 | 
						|
  try {
 | 
						|
    engine = await Services.search.addEngine(url, "", false);
 | 
						|
  } catch (errCode) {
 | 
						|
    ok(false, "addEngine failed with error code " + errCode);
 | 
						|
    throw errCode;
 | 
						|
  }
 | 
						|
 | 
						|
  info("Search engine added: " + basename);
 | 
						|
  registerCleanupFunction(async () => {
 | 
						|
    try {
 | 
						|
      await Services.search.removeEngine(engine);
 | 
						|
    } catch (ex) { /* Can't remove the engine more than once */ }
 | 
						|
  });
 | 
						|
 | 
						|
  return engine;
 | 
						|
}
 |