diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 68b88d3f1400..def242bd7a3e 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -556,7 +556,8 @@ var shell = { manifestURL: msg.manifest, isActivity: (msg.type == 'activity'), target: msg.target, - expectingSystemMessage: true + expectingSystemMessage: true, + extra: msg.extra }); }, diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index de3bccfe4857..c6192876aff6 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "701cd7f0334bf2507c8531f8a1a800cb6f992d39", + "revision": "72f1b7c657c65389c843dcd032e5bb787f4afafc", "repo_path": "/integration/gaia-central" } diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 79b855e449aa..ba71000db3fd 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -472,6 +472,10 @@ pref("dom.disable_window_move_resize", false); // prevent JS from monkeying with window focus, etc pref("dom.disable_window_flip", true); +// Disable touch events on Desktop Firefox by default until they are properly +// supported (bug 736048) +pref("dom.w3c_touch_events.enabled", 0); + // popups.policy 1=allow,2=reject pref("privacy.popups.policy", 1); pref("privacy.popups.usecustom", true); diff --git a/browser/base/content/abouthome/aboutHome.js b/browser/base/content/abouthome/aboutHome.js index f385cd2fc4dd..e0f3fbd7efd0 100644 --- a/browser/base/content/abouthome/aboutHome.js +++ b/browser/base/content/abouthome/aboutHome.js @@ -294,13 +294,6 @@ function onSearchSubmit(aEvent) let searchURL = document.documentElement.getAttribute("searchEngineURL"); if (searchURL && searchTerms.length > 0) { - const SEARCH_TOKENS = { - "_searchTerms_": encodeURIComponent(searchTerms) - } - for (let key in SEARCH_TOKENS) { - searchURL = searchURL.replace(key, SEARCH_TOKENS[key]); - } - // Send an event that a search was performed. This was originally // added so Firefox Health Report could record that a search from // about:home had occurred. @@ -308,7 +301,42 @@ function onSearchSubmit(aEvent) let event = new CustomEvent("AboutHomeSearchEvent", {detail: engineName}); document.dispatchEvent(event); - window.location.href = searchURL; + const SEARCH_TOKEN = "_searchTerms_"; + let searchPostData = document.documentElement.getAttribute("searchEnginePostData"); + if (searchPostData) { + // Check if a post form already exists. If so, remove it. + const POST_FORM_NAME = "searchFormPost"; + let form = document.forms[POST_FORM_NAME]; + if (form) { + form.parentNode.removeChild(form); + } + + // Create a new post form. + form = document.body.appendChild(document.createElement("form")); + form.setAttribute("name", POST_FORM_NAME); + // Set the URL to submit the form to. + form.setAttribute("action", searchURL.replace(SEARCH_TOKEN, searchTerms)); + form.setAttribute("method", "post"); + + // Create new elements for search param. + searchPostData = searchPostData.split("&"); + for (let postVar of searchPostData) { + let [name, value] = postVar.split("="); + if (value == SEARCH_TOKEN) { + value = searchTerms; + } + let input = document.createElement("input"); + input.setAttribute("type", "hidden"); + input.setAttribute("name", name); + input.setAttribute("value", value); + form.appendChild(input); + } + // Submit the form. + form.submit(); + } else { + searchURL = searchURL.replace(SEARCH_TOKEN, encodeURIComponent(searchTerms)); + window.location.href = searchURL; + } } aEvent.preventDefault(); diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 1b2c280ea15e..d386360d9198 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1040,7 +1040,6 @@ var gBrowserInit = { OfflineApps.init(); IndexedDBPromptHelper.init(); gFormSubmitObserver.init(); - SocialUI.init(); AddonManager.addAddonListener(AddonsMgrListener); WebrtcIndicator.init(); @@ -1101,12 +1100,7 @@ var gBrowserInit = { // initialize the session-restore service (in case it's not already running) let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); - ss.init(window); - - // Enable the Restore Last Session command if needed - if (ss.canRestoreLastSession && - !PrivateBrowsingUtils.isWindowPrivate(window)) - goSetCommandEnabled("Browser:RestoreLastSession", true); + let ssPromise = ss.init(window); PlacesToolbarHelper.init(); @@ -1169,7 +1163,6 @@ var gBrowserInit = { #endif gBrowserThumbnails.init(); - TabView.init(); setUrlAndSearchBarWidthForConditionalForwardButton(); window.addEventListener("resize", function resizeHandler(event) { @@ -1284,8 +1277,19 @@ var gBrowserInit = { #endif #endif + ssPromise.then(() =>{ + // Enable the Restore Last Session command if needed + if (ss.canRestoreLastSession && + !PrivateBrowsingUtils.isWindowPrivate(window)) + goSetCommandEnabled("Browser:RestoreLastSession", true); + + TabView.init(); + SocialUI.init(); + + setTimeout(function () { BrowserChromeTest.markAsReady(); }, 0); + }); + Services.obs.notifyObservers(window, "browser-delayed-startup-finished", ""); - setTimeout(function () { BrowserChromeTest.markAsReady(); }, 0); TelemetryTimestamps.add("delayedStartupFinished"); }, @@ -2310,6 +2314,9 @@ function BrowserOnAboutPageLoad(doc) { let updateSearchEngine = function() { let engine = AboutHomeUtils.defaultSearchEngine; docElt.setAttribute("searchEngineName", engine.name); + docElt.setAttribute("searchEnginePostData", engine.postDataString || ""); + // Again, keep the searchEngineURL as the last attribute, because the + // mutation observer in aboutHome.js is counting on that. docElt.setAttribute("searchEngineURL", engine.searchURL); }; updateSearchEngine(); diff --git a/browser/base/content/test/browser_aboutHome.js b/browser/base/content/test/browser_aboutHome.js index 6de36081f2e4..9e4b590071fb 100644 --- a/browser/base/content/test/browser_aboutHome.js +++ b/browser/base/content/test/browser_aboutHome.js @@ -242,10 +242,12 @@ let gTests = [ promiseBrowserAttributes(gBrowser.selectedTab).then(function() { // Test if the update propagated checkSearchUI(unusedEngines[0]); + searchbar.currentEngine = currEngine; deferred.resolve(); }); - // The following cleanup function will set currentEngine back to the previous engine + // The following cleanup function will set currentEngine back to the previous + // engine if we fail to do so above. registerCleanupFunction(function() { searchbar.currentEngine = currEngine; }); @@ -254,6 +256,58 @@ let gTests = [ searchbar.select(); return deferred.promise; } +}, + +{ + desc: "Check POST search engine support", + setup: function() {}, + run: function() + { + let deferred = Promise.defer(); + let currEngine = Services.search.defaultEngine; + let searchObserver = function search_observer(aSubject, aTopic, aData) { + let engine = aSubject.QueryInterface(Ci.nsISearchEngine); + info("Observer: " + aData + " for " + engine.name); + + if (aData != "engine-added") + return; + + if (engine.name != "POST Search") + return; + + Services.search.defaultEngine = engine; + + registerCleanupFunction(function() { + Services.search.removeEngine(engine); + Services.search.defaultEngine = currEngine; + }); + + + // Ready to execute the tests! + let needle = "Search for something awesome."; + let document = gBrowser.selectedTab.linkedBrowser.contentDocument; + let searchText = document.getElementById("searchText"); + + waitForLoad(function() { + let loadedText = gBrowser.contentDocument.body.textContent; + ok(loadedText, "search page loaded"); + is(loadedText, "searchterms=" + escape(needle.replace(/\s/g, "+")), + "Search text should arrive correctly"); + deferred.resolve(); + }); + + searchText.value = needle; + searchText.focus(); + EventUtils.synthesizeKey("VK_RETURN", {}); + }; + Services.obs.addObserver(searchObserver, "browser-search-engine-modified", false); + registerCleanupFunction(function () { + Services.obs.removeObserver(searchObserver, "browser-search-engine-modified"); + }); + Services.search.addEngine("http://test:80/browser/browser/base/content/test/POSTSearchEngine.xml", + Ci.nsISearchEngine.DATA_XML, null, false); + return deferred.promise; + } } ]; @@ -442,3 +496,15 @@ function getNumberOfSearchesByDate(aEngineName, aData, aDate) { return 0; // No records found. } + +function waitForLoad(cb) { + let browser = gBrowser.selectedBrowser; + browser.addEventListener("load", function listener() { + if (browser.currentURI.spec == "about:blank") + return; + info("Page loaded: " + browser.currentURI.spec); + browser.removeEventListener("load", listener, true); + + cb(); + }, true); +} diff --git a/browser/base/content/test/social/browser_social_window.js b/browser/base/content/test/social/browser_social_window.js index f6a0afab038c..14d4aa7c58e8 100644 --- a/browser/base/content/test/social/browser_social_window.js +++ b/browser/base/content/test/social/browser_social_window.js @@ -17,6 +17,7 @@ function resetSocial() { } let createdWindows = []; +let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore); function openWindowAndWaitForInit(callback) { // this notification tells us SocialUI.init() has been run... @@ -26,8 +27,12 @@ function openWindowAndWaitForInit(callback) { Services.obs.addObserver(function providerSet(subject, topic, data) { Services.obs.removeObserver(providerSet, topic); info(topic + " observer was notified - continuing test"); - // executeSoon to let the browser UI observers run first - executeSoon(function() {callback(w)}); + // We need to wait for the SessionStore as well, since + // SocialUI.init() is also waiting on it. + ss.init(w).then(function () { + executeSoon(function() {callback(w);}); + }); + }, topic, false); } diff --git a/browser/components/sessionstore/nsISessionStore.idl b/browser/components/sessionstore/nsISessionStore.idl index aa710921f120..153623d958a9 100644 --- a/browser/components/sessionstore/nsISessionStore.idl +++ b/browser/components/sessionstore/nsISessionStore.idl @@ -25,13 +25,13 @@ interface nsIDOMNode; * |gBrowser.tabContainer| such as e.g. |gBrowser.selectedTab|. */ -[scriptable, uuid(0aa5492c-15ad-4376-8eac-28895796826e)] +[scriptable, uuid(092fa0cc-e99b-11e2-a2a3-a25b4f45d8e2)] interface nsISessionStore : nsISupports { /** * Initialize the service */ - void init(in nsIDOMWindow aWindow); + jsval init(in nsIDOMWindow aWindow); /** * Is it possible to restore the previous session. Will always be false when diff --git a/browser/components/sessionstore/src/SessionStore.jsm b/browser/components/sessionstore/src/SessionStore.jsm index 539687e9f047..0c2e06be5905 100644 --- a/browser/components/sessionstore/src/SessionStore.jsm +++ b/browser/components/sessionstore/src/SessionStore.jsm @@ -79,7 +79,7 @@ Cu.import("resource://gre/modules/TelemetryTimestamps.jsm", this); Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", this); Cu.import("resource://gre/modules/osfile.jsm", this); Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm", this); -Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", this); +Cu.import("resource://gre/modules/Promise.jsm", this); Cu.import("resource://gre/modules/Task.jsm", this); XPCOMUtils.defineLazyServiceGetter(this, "gSessionStartup", @@ -139,7 +139,7 @@ this.SessionStore = { }, init: function ss_init(aWindow) { - SessionStoreInternal.init(aWindow); + return SessionStoreInternal.init(aWindow); }, getBrowserState: function ss_getBrowserState() { @@ -579,9 +579,11 @@ let SessionStoreInternal = { let self = this; this.initService(); - this._promiseInitialization.promise.then( + return this._promiseInitialization.promise.then( function onSuccess() { - self.onLoad(aWindow); + if (!aWindow.closed) { + self.onLoad(aWindow); + } } ); }, diff --git a/browser/components/sessionstore/src/_SessionFile.jsm b/browser/components/sessionstore/src/_SessionFile.jsm index 4a69b36be470..e96784b10316 100644 --- a/browser/components/sessionstore/src/_SessionFile.jsm +++ b/browser/components/sessionstore/src/_SessionFile.jsm @@ -33,7 +33,7 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://gre/modules/osfile/_PromiseWorker.jsm", this); -Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js"); +Cu.import("resource://gre/modules/Promise.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"); diff --git a/browser/components/sessionstore/src/nsSessionStartup.js b/browser/components/sessionstore/src/nsSessionStartup.js index 112d0e8a7af0..6d8c7925bf1a 100644 --- a/browser/components/sessionstore/src/nsSessionStartup.js +++ b/browser/components/sessionstore/src/nsSessionStartup.js @@ -39,7 +39,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/TelemetryStopwatch.jsm"); Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); -Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js"); +Cu.import("resource://gre/modules/Promise.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "_SessionFile", "resource:///modules/sessionstore/_SessionFile.jsm"); diff --git a/browser/devtools/debugger/debugger-panes.js b/browser/devtools/debugger/debugger-panes.js index 29491fc1b8b5..f3a945d46073 100644 --- a/browser/devtools/debugger/debugger-panes.js +++ b/browser/devtools/debugger/debugger-panes.js @@ -36,7 +36,8 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, { dumpn("Initializing the SourcesView"); this.widget = new SideMenuWidget(document.getElementById("sources"), { - showCheckboxes: true + showCheckboxes: true, + showArrows: true }); this.emptyText = L10N.getStr("noSourcesText"); this.unavailableText = L10N.getStr("noMatchingSourcesText"); diff --git a/browser/devtools/profiler/sidebar.js b/browser/devtools/profiler/sidebar.js index 358ed462fd70..f4be144ef9b9 100644 --- a/browser/devtools/profiler/sidebar.js +++ b/browser/devtools/profiler/sidebar.js @@ -23,7 +23,7 @@ function Sidebar(el) { EventEmitter.decorate(this); this.document = el.ownerDocument; - this.widget = new SideMenuWidget(el); + this.widget = new SideMenuWidget(el, { showArrows: true }); this.widget.notice = L10N.getStr("profiler.sidebarNotice"); this.widget.addEventListener("select", (ev) => { @@ -117,4 +117,4 @@ Sidebar.prototype = Heritage.extend(WidgetMethods, { } }); -module.exports = Sidebar; \ No newline at end of file +module.exports = Sidebar; diff --git a/browser/modules/AboutHomeUtils.jsm b/browser/modules/AboutHomeUtils.jsm index 09d395fee082..847948a008da 100644 --- a/browser/modules/AboutHomeUtils.jsm +++ b/browser/modules/AboutHomeUtils.jsm @@ -25,13 +25,11 @@ this.AboutHomeUtils = { get defaultSearchEngine() { let defaultEngine = Services.search.defaultEngine; let submission = defaultEngine.getSubmission("_searchTerms_", null, "homepage"); - if (submission.postData) { - throw new Error("Home page does not support POST search engines."); - } return Object.freeze({ name: defaultEngine.name, - searchURL: submission.uri.spec + searchURL: submission.uri.spec, + postDataString: submission.postDataString }); }, diff --git a/content/base/test/test_CSP_bug888172.html b/content/base/test/test_CSP_bug888172.html index fa95b8909dfd..d594ad553944 100644 --- a/content/base/test/test_CSP_bug888172.html +++ b/content/base/test/test_CSP_bug888172.html @@ -60,15 +60,15 @@ SpecialPowers.pushPrefEnv( {'set':[["security.csp.speccompliant", true]]}, function () { document.getElementById('testframe1').src = 'file_CSP_bug888172.sjs?csp=' + - escape("Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval'"); + escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'"); document.getElementById('testframe1').addEventListener('load', checkDefaultSrcOnly, false); document.getElementById('testframe2').src = 'file_CSP_bug888172.sjs?csp=' + - escape("Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self'"); + escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; script-src 'self'"); document.getElementById('testframe2').addEventListener('load', checkDefaultSrcWithScriptSrc, false); document.getElementById('testframe3').src = 'file_CSP_bug888172.sjs?csp=' + - escape("Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self'"); + escape("default-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self'"); document.getElementById('testframe3').addEventListener('load', checkDefaultSrcWithStyleSrc, false); } ); diff --git a/content/media/MediaRecorder.cpp b/content/media/MediaRecorder.cpp index d4738635e636..f4a31b217a54 100644 --- a/content/media/MediaRecorder.cpp +++ b/content/media/MediaRecorder.cpp @@ -147,7 +147,7 @@ MediaRecorder::ExtractEncodedData() mEncodedBufferCache->AppendBuffer(outputBufs[i]); } - if ((TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) { + if (mTimeSlice > 0 && (TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) { NS_DispatchToMainThread(new PushBlobTask(this)); lastBlobTimeStamp = TimeStamp::Now(); } diff --git a/dom/activities/src/ActivitiesService.jsm b/dom/activities/src/ActivitiesService.jsm index 8ff9bf34ff50..955e0081b236 100644 --- a/dom/activities/src/ActivitiesService.jsm +++ b/dom/activities/src/ActivitiesService.jsm @@ -237,7 +237,11 @@ let Activities = { "target": result.description }, Services.io.newURI(result.description.href, null, null), - Services.io.newURI(result.manifest, null, null)); + Services.io.newURI(result.manifest, null, null), + { + "manifestURL": Activities.callers[aMsg.id].manifestURL, + "pageURL": Activities.callers[aMsg.id].pageURL + }); if (!result.description.returnValue) { Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireSuccess", { diff --git a/dom/bluetooth/BluetoothService.cpp b/dom/bluetooth/BluetoothService.cpp index 5a60462ab104..5045df1f5ff5 100644 --- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -798,7 +798,9 @@ BluetoothService::Notify(const BluetoothSignal& aData) do_GetService("@mozilla.org/system-message-internal;1"); NS_ENSURE_TRUE_VOID(systemMessenger); - systemMessenger->BroadcastMessage(type, OBJECT_TO_JSVAL(obj)); + systemMessenger->BroadcastMessage(type, + OBJECT_TO_JSVAL(obj), + JS::UndefinedValue()); } void diff --git a/dom/bluetooth/BluetoothUtils.cpp b/dom/bluetooth/BluetoothUtils.cpp index 66a3bf510efd..c9b58482f211 100644 --- a/dom/bluetooth/BluetoothUtils.cpp +++ b/dom/bluetooth/BluetoothUtils.cpp @@ -124,7 +124,9 @@ BroadcastSystemMessage(const nsAString& aType, do_GetService("@mozilla.org/system-message-internal;1"); NS_ENSURE_TRUE(systemMessenger, false); - systemMessenger->BroadcastMessage(aType, OBJECT_TO_JSVAL(obj)); + systemMessenger->BroadcastMessage(aType, + OBJECT_TO_JSVAL(obj), + JS::UndefinedValue()); return true; } diff --git a/dom/messages/SystemMessageInternal.js b/dom/messages/SystemMessageInternal.js index b791ae48e7d5..a8bb0df840d3 100644 --- a/dom/messages/SystemMessageInternal.js +++ b/dom/messages/SystemMessageInternal.js @@ -168,7 +168,7 @@ SystemMessageInternal.prototype = { return page; }, - sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) { + sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI, aExtra) { // Buffer system messages until the webapps' registration is ready, // so that we can know the correct pages registered to be sent. if (!this._webappsRegistryReady) { @@ -176,7 +176,8 @@ SystemMessageInternal.prototype = { type: aType, msg: aMessage, pageURI: aPageURI, - manifestURI: aManifestURI }); + manifestURI: aManifestURI, + extra: aExtra }); return; } @@ -185,13 +186,15 @@ SystemMessageInternal.prototype = { let messageID = gUUIDGenerator.generateUUID().toString(); debug("Sending " + aType + " " + JSON.stringify(aMessage) + - " for " + aPageURI.spec + " @ " + aManifestURI.spec); + " for " + aPageURI.spec + " @ " + aManifestURI.spec + + '; extra: ' + JSON.stringify(aExtra)); let result = this._sendMessageCommon(aType, aMessage, messageID, aPageURI.spec, - aManifestURI.spec); + aManifestURI.spec, + aExtra); debug("Returned status of sending message: " + result); // Don't need to open the pages and queue the system message @@ -205,20 +208,21 @@ SystemMessageInternal.prototype = { // Queue this message in the corresponding pages. this._queueMessage(page, aMessage, messageID); - if (result === MSG_SENT_FAILURE_APP_NOT_RUNNING) { - // Don't open the page again if we already sent the message to it. - this._openAppPage(page, aMessage); - } + if (result === MSG_SENT_FAILURE_APP_NOT_RUNNING) { + // Don't open the page again if we already sent the message to it. + this._openAppPage(page, aMessage, aExtra); + } } }, - broadcastMessage: function broadcastMessage(aType, aMessage) { + broadcastMessage: function broadcastMessage(aType, aMessage, aExtra) { // Buffer system messages until the webapps' registration is ready, // so that we can know the correct pages registered to be broadcasted. if (!this._webappsRegistryReady) { this._bufferedSysMsgs.push({ how: "broadcast", type: aType, - msg: aMessage }); + msg: aMessage, + extra: aExtra }); return; } @@ -226,7 +230,8 @@ SystemMessageInternal.prototype = { // clean it up from the pending message queue when apps receive it. let messageID = gUUIDGenerator.generateUUID().toString(); - debug("Broadcasting " + aType + " " + JSON.stringify(aMessage)); + debug("Broadcasting " + aType + " " + JSON.stringify(aMessage) + + '; extra = ' + JSON.stringify(aExtra)); // Find pages that registered an handler for this type. this._pages.forEach(function(aPage) { if (aPage.type == aType) { @@ -234,7 +239,8 @@ SystemMessageInternal.prototype = { aMessage, messageID, aPage.uri, - aPage.manifest); + aPage.manifest, + aExtra); debug("Returned status of sending message: " + result); @@ -249,7 +255,7 @@ SystemMessageInternal.prototype = { if (result === MSG_SENT_FAILURE_APP_NOT_RUNNING) { // Open app pages to handle their pending messages. - this._openAppPage(aPage, aMessage); + this._openAppPage(aPage, aMessage, aExtra); } } }, this); @@ -503,10 +509,10 @@ SystemMessageInternal.prototype = { switch (aSysMsg.how) { case "send": this.sendMessage( - aSysMsg.type, aSysMsg.msg, aSysMsg.pageURI, aSysMsg.manifestURI); + aSysMsg.type, aSysMsg.msg, aSysMsg.pageURI, aSysMsg.manifestURI, aSysMsg.extra); break; case "broadcast": - this.broadcastMessage(aSysMsg.type, aSysMsg.msg); + this.broadcastMessage(aSysMsg.type, aSysMsg.msg, aSysMsg.extra); break; } }, this); @@ -524,11 +530,12 @@ SystemMessageInternal.prototype = { } }, - _openAppPage: function _openAppPage(aPage, aMessage) { + _openAppPage: function _openAppPage(aPage, aMessage, aExtra) { // We don't need to send the full object to observers. let page = { uri: aPage.uri, manifest: aPage.manifest, type: aPage.type, + extra: aExtra, target: aMessage.target }; debug("Asking to open " + JSON.stringify(page)); Services.obs.notifyObservers(this, "system-messages-open-app", JSON.stringify(page)); @@ -559,7 +566,7 @@ SystemMessageInternal.prototype = { }, _sendMessageCommon: - function _sendMessageCommon(aType, aMessage, aMessageID, aPageURI, aManifestURI) { + function _sendMessageCommon(aType, aMessage, aMessageID, aPageURI, aManifestURI, aExtra) { // Don't send the system message not granted by the app's permissions. if (!SystemMessagePermissionsChecker .isSystemMessagePermittedToSend(aType, diff --git a/dom/messages/interfaces/nsISystemMessagesInternal.idl b/dom/messages/interfaces/nsISystemMessagesInternal.idl index af5010cf7ae0..f529d7c71d13 100644 --- a/dom/messages/interfaces/nsISystemMessagesInternal.idl +++ b/dom/messages/interfaces/nsISystemMessagesInternal.idl @@ -9,7 +9,7 @@ interface nsIDOMWindow; // Implemented by the contract id @mozilla.org/system-message-internal;1 -[scriptable, uuid(d8de761a-94fe-44d5-80eb-3c8bd8cd7d0b)] +[scriptable, uuid(6296a314-2abf-4cd0-9097-5e81ee6832e2)] interface nsISystemMessagesInternal : nsISupports { /* @@ -18,16 +18,20 @@ interface nsISystemMessagesInternal : nsISupports * @param message The message payload. * @param pageURI The URI of the page that will be opened. * @param manifestURI The webapp's manifest URI. + * @param extra Extra opaque information that will be passed around in the observer + * notification to open the page. */ - void sendMessage(in DOMString type, in jsval message, in nsIURI pageURI, in nsIURI manifestURI); + void sendMessage(in DOMString type, in jsval message, in nsIURI pageURI, in nsIURI manifestURI, [optional] in jsval extra); /* * Allow any internal user to broadcast a message of a given type. * The application that registers the message will be launched. * @param type The type of the message to be sent. * @param message The message payload. + * @param extra Extra opaque information that will be passed around in the observer + * notification to open the page. */ - void broadcastMessage(in DOMString type, in jsval message); + void broadcastMessage(in DOMString type, in jsval message, [optional] in jsval extra); /* * Registration of a page that wants to be notified of a message type. diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index 3b2e67020f14..df4a1c01e2f4 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -4896,12 +4896,6 @@ RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options) if (DEBUG) debug("Signal strength " + JSON.stringify(obj)); obj.rilMessageType = "signalstrengthchange"; this.sendChromeMessage(obj); - - if (this.cachedDialRequest && obj.gsmDBM && obj.gsmRelative) { - // Radio is ready for making the cached emergency call. - this.cachedDialRequest.callback(); - this.cachedDialRequest = null; - } }; RIL[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length, options) { this._receivedNetworkInfo(NETWORK_INFO_VOICE_REGISTRATION_STATE); @@ -4914,6 +4908,15 @@ RIL[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STAT if (DEBUG) debug("voice registration state: " + state); this._processVoiceRegistrationState(state); + + if (this.cachedDialRequest && + (this.voiceRegistrationState.emergencyCallsOnly || + this.voiceRegistrationState.connected) && + this.voiceRegistrationState.radioTech != NETWORK_CREG_TECH_UNKNOWN) { + // Radio is ready for making the cached emergency call. + this.cachedDialRequest.callback(); + this.cachedDialRequest = null; + } }; RIL[REQUEST_DATA_REGISTRATION_STATE] = function REQUEST_DATA_REGISTRATION_STATE(length, options) { this._receivedNetworkInfo(NETWORK_INFO_DATA_REGISTRATION_STATE); diff --git a/dom/wappush/src/gonk/CpPduHelper.jsm b/dom/wappush/src/gonk/CpPduHelper.jsm new file mode 100644 index 000000000000..0c68a03740e9 --- /dev/null +++ b/dom/wappush/src/gonk/CpPduHelper.jsm @@ -0,0 +1,276 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +let WSP = {}; +Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP); +let WBXML = {}; +Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML); + +// set to true to see debug messages +let DEBUG = WBXML.DEBUG_ALL | false; + +/** + * Public identifier for CP + * + * @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx + */ +const PUBLIC_IDENTIFIER_CP = "-//WAPFORUM//DTD PROV 1.0//EN"; + +this.PduHelper = { + + /** + * @param data + * A wrapped object containing raw PDU data. + * @param contentType + * Content type of incoming CP message, should be "text/vnd.wap.connectivity-xml" + * or "application/vnd.wap.connectivity-wbxml". + * + * @return A message object containing attribute content and contentType. + * |content| will contain string of decoded CP message if successfully + * decoded, or raw data if failed. + * |contentType| will be string representing corresponding type of + * content. + */ + parse: function parse_cp(data, contentType) { + // We only need content and contentType + let msg = { + contentType: contentType + }; + + /** + * Message is compressed by WBXML, decode into string. + * + * @see WAP-192-WBXML-20010725-A + */ + if (contentType === "application/vnd.wap.connectivity-wbxml") { + let appToken = { + publicId: PUBLIC_IDENTIFIER_CP, + tagTokenList: CP_TAG_FIELDS, + attrTokenList: CP_ATTRIBUTE_FIELDS, + valueTokenList: CP_VALUE_FIELDS, + globalTokenOverride: null + } + + try { + let parseResult = WBXML.PduHelper.parse(data, appToken, msg); + msg.content = parseResult.content; + msg.contentType = "text/vnd.wap.connectivity-xml"; + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; + } + + return msg; + } + + /** + * Message is plain text, transform raw to string. + */ + try { + let stringData = WSP.Octet.decodeMultiple(data, data.array.length); + msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8"); + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; + } + return msg; + + } +}; + +/** + * Tag tokens + * + * @see WAP-183-ProvCont-20010724-A, clause 8.1 + */ +const CP_TAG_FIELDS = (function () { + let names = {}; + function add(name, number) { + let entry = { + name: name, + number: number, + }; + names[number] = entry; + } + + add("wap-provisioningdoc", 0x05); + add("characteristic", 0x06); + add("parm", 0x07); + + return names; +})(); + +/** + * Attribute Tokens + * + * @see WAP-183-ProvCont-20010724-A, clause 8.2 + */ +const CP_ATTRIBUTE_FIELDS = (function () { + let names = {}; + function add(name, value, number) { + let entry = { + name: name, + value: value, + number: number, + }; + names[number] = entry; + } + + add("name", "", 0x05); + add("value", "", 0x06); + add("name", "NAME", 0x07); + add("name", "NAP-ADDRESS", 0x08); + add("name", "NAP-ADDRTYPE", 0x09); + add("name", "CALLTYPE", 0x0A); + add("name", "VALIDUNTIL", 0x0B); + add("name", "AUTHTYPE", 0x0C); + add("name", "AUTHNAME", 0x0D); + add("name", "AUTHSECRET", 0x0E); + add("name", "LINGER", 0x0F); + add("name", "BEARER", 0x10); + add("name", "NAPID", 0x11); + add("name", "COUNTRY", 0x12); + add("name", "NETWORK", 0x13); + add("name", "INTERNET", 0x14); + add("name", "PROXY-ID", 0x15); + add("name", "PROXY-PROVIDER-ID", 0x16); + add("name", "DOMAIN", 0x17); + add("name", "PROVURL", 0x18); + add("name", "PXAUTH-TYPE", 0x19); + add("name", "PXAUTH-ID", 0x1A); + add("name", "PXAUTH-PW", 0x1B); + add("name", "STARTPAGE", 0x1C); + add("name", "BASAUTH-ID", 0x1D); + add("name", "BASAUTH-PW", 0x1E); + add("name", "PUSHENABLED", 0x1F); + add("name", "PXADDR", 0x20); + add("name", "PXADDRTYPE", 0x21); + add("name", "TO-NAPID", 0x22); + add("name", "PORTNBR", 0x23); + add("name", "SERVICE", 0x24); + add("name", "LINKSPEED", 0x25); + add("name", "DNLINKSPEED", 0x26); + add("name", "LOCAL-ADDR", 0x27); + add("name", "LOCAL-ADDRTYPE", 0x28); + add("name", "CONTEXT-ALLOW", 0x29); + add("name", "TRUST", 0x2A); + add("name", "MASTER", 0x2B); + add("name", "SID", 0x2C); + add("name", "SOC", 0x2D); + add("name", "WSP-VERSION", 0x2E); + add("name", "PHYSICAL-PROXY-ID", 0x2F); + add("name", "CLIENT-ID", 0x30); + add("name", "DELIVERY-ERR-PDU", 0x31); + add("name", "DELIVERY-ORDER", 0x32); + add("name", "TRAFFIC-CLASS", 0x33); + add("name", "MAX-SDU-SIZE", 0x34); + add("name", "MAX-BITRATE-UPLINK", 0x35); + add("name", "MAX-BITRATE-DNLINK", 0x36); + add("name", "RESIDUAL-BER", 0x37); + add("name", "SDU-ERROR-RATIO", 0x38); + add("name", "TRAFFIC-HANDL-PRIO", 0x39); + add("name", "TRANSFER-DELAY", 0x3A); + add("name", "GUARANTEED-BITRATE-UPLINK", 0x3B); + add("name", "GUARANTEED-BITRATE-DNLINK", 0x3C); + add("version", "", 0x45); + add("version", "1.0", 0x46); + add("type", "", 0x50); + add("type", "PXLOGICAL", 0x51); + add("type", "PXPHYSICAL", 0x52); + add("type", "PORT", 0x53); + add("type", "VALIDITY", 0x54); + add("type", "NAPDEF", 0x55); + add("type", "BOOTSTRAP", 0x56); +/* + * Mark out VENDORCONFIG so if it is contained in message, parse + * will failed and raw data is returned. + */ +// add("type", "VENDORCONFIG", 0x57); + add("type", "CLIENTIDENTITY", 0x58); + add("type", "PXAUTHINFO", 0x59); + add("type", "NAPAUTHINFO", 0x5A); + + return names; +})(); + +const CP_VALUE_FIELDS = (function () { + let names = {}; + function add(value, number) { + let entry = { + value: value, + number: number, + }; + names[number] = entry; + } + + add("IPV4", 0x85); + add("IPV6", 0x86); + add("E164", 0x87); + add("ALPHA", 0x88); + add("APN", 0x89); + add("SCODE", 0x8A); + add("TETRA-ITSI", 0x8B); + add("MAN", 0x8C); + add("ANALOG-MODEM", 0x90); + add("V.120", 0x91); + add("V.110", 0x92); + add("X.31", 0x93); + add("BIT-TRANSPARENT", 0x94); + add("DIRECT-ASYNCHRONOUS-DATA-SERVICE", 0x95); + add("PAP", 0x9A); + add("CHAP", 0x9B); + add("HTTP-BASIC", 0x9C); + add("HTTP-DIGEST", 0x9D); + add("WTLS-SS", 0x9E); + add("GSM-USSD", 0xA2); + add("GSM-SMS", 0xA3); + add("ANSI-136-GUTS", 0xA4); + add("IS-95-CDMA-SMS", 0xA5); + add("IS-95-CDMA-CSD", 0xA6); + add("IS-95-CDMA-PAC", 0xA7); + add("ANSI-136-CSD", 0xA8); + add("ANSI-136-GPRS", 0xA9); + add("GSM-CSD", 0xAA); + add("GSM-GPRS", 0xAB); + add("AMPS-CDPD", 0xAC); + add("PDC-CSD", 0xAD); + add("PDC-PACKET", 0xAE); + add("IDEN-SMS", 0xAF); + add("IDEN-CSD", 0xB0); + add("IDEN-PACKET", 0xB1); + add("FLEX/REFLEX", 0xB2); + add("PHS-SMS", 0xB3); + add("PHS-CSD", 0xB4); + add("TETRA-SDS", 0xB5); + add("TETRA-PACKET", 0xB6); + add("ANSI-136-GHOST", 0xB7); + add("MOBITEX-MPAK", 0xB8); + add("AUTOBOUDING", 0xC5); + add("CL-WSP", 0xCA); + add("CO-WSP", 0xCB); + add("CL-SEC-WSP", 0xCC); + add("CO-SEC-WSP", 0xCD); + add("CL-SEC-WTA", 0xCE); + add("CO-SEC-WTA", 0xCF); + + return names; +})(); + +let debug; +if (DEBUG) { + debug = function (s) { + dump("-$- CpPduHelper: " + s + "\n"); + }; +} else { + debug = function (s) {}; +} + +this.EXPORTED_SYMBOLS = [ + // Parser + "PduHelper", +]; diff --git a/dom/wappush/src/gonk/SiPduHelper.jsm b/dom/wappush/src/gonk/SiPduHelper.jsm index 95585f5f2045..dc8bd5b3c8e4 100644 --- a/dom/wappush/src/gonk/SiPduHelper.jsm +++ b/dom/wappush/src/gonk/SiPduHelper.jsm @@ -65,22 +65,28 @@ this.PduHelper = { /** * @param data * A wrapped object containing raw PDU data. - * @param contentType [optional] + * @param contentType * Content type of incoming SI message, should be "text/vnd.wap.si" or * "application/vnd.wap.sic". - * Default value is "application/vnd.wap.sic". * - * @return A SI message object or null in case of errors found. + * @return A message object containing attribute content and contentType. + * |content| will contain string of decoded SI message if successfully + * decoded, or raw data if failed. + * |contentType| will be string representing corresponding type of + * content. */ parse: function parse_si(data, contentType) { - let msg = {}; + // We only need content and contentType + let msg = { + contentType: contentType + }; /** * Message is compressed by WBXML, decode into string. * * @see WAP-192-WBXML-20010725-A */ - if (!contentType || contentType === "application/vnd.wap.sic") { + if (contentType === "application/vnd.wap.sic") { let globalTokenOverride = {}; globalTokenOverride[0xC3] = { number: 0xC3, @@ -89,43 +95,36 @@ this.PduHelper = { let appToken = { publicId: PUBLIC_IDENTIFIER_SI, - tagToken: SI_TAG_FIELDS, - attrToken: SI_ATTRIBUTE_FIELDS, + tagTokenList: SI_TAG_FIELDS, + attrTokenList: SI_ATTRIBUTE_FIELDS, + valueTokenList: SI_VALUE_FIELDS, globalTokenOverride: globalTokenOverride } - WBXML.PduHelper.parse(data, appToken, msg); - - msg.contentType = "text/vnd.wap.si"; + try { + let parseResult = WBXML.PduHelper.parse(data, appToken); + msg.content = parseResult.content; + msg.contentType = "text/vnd.wap.si"; + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; + } return msg; } /** * Message is plain text, transform raw to string. */ - if (contentType === "text/vnd.wap.si") { + try { let stringData = WSP.Octet.decodeMultiple(data, data.array.length); - msg.publicId = PUBLIC_IDENTIFIER_SI; msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8"); - msg.contentType = "text/vnd.wap.si"; - return msg; + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; } + return msg; - return null; - }, - - /** - * @param multiStream - * An exsiting nsIMultiplexInputStream. - * @param msg - * A SI message object. - * - * @return An instance of nsIMultiplexInputStream or null in case of errors. - */ - compose: function compose_si(multiStream, msg) { - // Composing SI message is not supported - return null; - }, + } }; /** @@ -140,7 +139,7 @@ const SI_TAG_FIELDS = (function () { name: name, number: number, }; - names[name] = names[number] = entry; + names[number] = entry; } add("si", 0x05); @@ -164,7 +163,7 @@ const SI_ATTRIBUTE_FIELDS = (function () { value: value, number: number, }; - names[name] = names[number] = entry; + names[number] = entry; } add("action", "signal-none", 0x05); @@ -181,10 +180,24 @@ const SI_ATTRIBUTE_FIELDS = (function () { add("si-expires", "", 0x10); add("si-id", "", 0x11); add("class", "", 0x12); - add("", ".com/", 0x85); - add("", ".edu/", 0x86); - add("", ".net/", 0x87); - add("", ".org/", 0x88); + + return names; +})(); + +const SI_VALUE_FIELDS = (function () { + let names = {}; + function add(value, number) { + let entry = { + value: value, + number: number, + }; + names[number] = entry; + } + + add(".com/", 0x85); + add(".edu/", 0x86); + add(".net/", 0x87); + add(".org/", 0x88); return names; })(); diff --git a/dom/wappush/src/gonk/SlPduHelper.jsm b/dom/wappush/src/gonk/SlPduHelper.jsm index 2fc1e9430dd9..eba294318198 100644 --- a/dom/wappush/src/gonk/SlPduHelper.jsm +++ b/dom/wappush/src/gonk/SlPduHelper.jsm @@ -26,61 +26,61 @@ this.PduHelper = { /** * @param data * A wrapped object containing raw PDU data. - * @param contentType [optional] + * @param contentType * Content type of incoming SL message, should be "text/vnd.wap.sl" or * "application/vnd.wap.slc". - * Default value is "application/vnd.wap.slc". * - * @return A SL message object or null in case of errors found. + * @return A message object containing attribute content and contentType. + * |content| will contain string of decoded SL message if successfully + * decoded, or raw data if failed. + * |contentType| will be string representing corresponding type of + * content. */ parse: function parse_sl(data, contentType) { - let msg = {}; + // We only need content and contentType + let msg = { + contentType: contentType + }; /** * Message is compressed by WBXML, decode into string. * * @see WAP-192-WBXML-20010725-A */ - if (!contentType || contentType === "application/vnd.wap.slc") { + if (contentType === "application/vnd.wap.slc") { let appToken = { publicId: PUBLIC_IDENTIFIER_SL, - tagToken: SL_TAG_FIELDS, - attrToken: SL_ATTRIBUTE_FIELDS, + tagTokenList: SL_TAG_FIELDS, + attrTokenList: SL_ATTRIBUTE_FIELDS, + valueTokenList: SL_VALUE_FIELDS, globalTokenOverride: null } - WBXML.PduHelper.parse(data, appToken, msg); + try { + let parseResult = WBXML.PduHelper.parse(data, appToken); + msg.content = parseResult.content; + msg.contentType = "text/vnd.wap.sl"; + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; + } - msg.contentType = "text/vnd.wap.sl"; return msg; } /** * Message is plain text, transform raw to string. */ - if (contentType === "text/vnd.wap.sl") { + try { let stringData = WSP.Octet.decodeMultiple(data, data.array.length); - msg.publicId = PUBLIC_IDENTIFIER_SL; msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8"); - msg.contentType = "text/vnd.wap.sl"; - return msg; + } catch (e) { + // Provide raw data if we failed to parse. + msg.content = data.array; } + return msg; - return null; - }, - - /** - * @param multiStream - * An exsiting nsIMultiplexInputStream. - * @param msg - * A SL message object. - * - * @return An instance of nsIMultiplexInputStream or null in case of errors. - */ - compose: function compose_sl(multiStream, msg) { - // Composing SL message is not supported - return null; - }, + } }; /** @@ -95,7 +95,7 @@ const SL_TAG_FIELDS = (function () { name: name, number: number, }; - names[name] = names[number] = entry; + names[number] = entry; } add("sl", 0x05); @@ -116,7 +116,7 @@ const SL_ATTRIBUTE_FIELDS = (function () { value: value, number: number, }; - names[name] = names[number] = entry; + names[number] = entry; } add("action", "execute-low", 0x05); @@ -127,10 +127,24 @@ const SL_ATTRIBUTE_FIELDS = (function () { add("href", "http://www.", 0x0A); add("href", "https://", 0x0B); add("href", "https://www.", 0x0C); - add("", ".com/", 0x85); - add("", ".edu/", 0x86); - add("", ".net/", 0x87); - add("", ".org/", 0x88); + + return names; +})(); + +const SL_VALUE_FIELDS = (function () { + let names = {}; + function add(value, number) { + let entry = { + value: value, + number: number, + }; + names[number] = entry; + } + + add(".com/", 0x85); + add(".edu/", 0x86); + add(".net/", 0x87); + add(".org/", 0x88); return names; })(); diff --git a/dom/wappush/src/gonk/WapPushManager.js b/dom/wappush/src/gonk/WapPushManager.js index d017ddd92bd3..96e87b0a4420 100644 --- a/dom/wappush/src/gonk/WapPushManager.js +++ b/dom/wappush/src/gonk/WapPushManager.js @@ -28,6 +28,12 @@ XPCOMUtils.defineLazyGetter(this, "SL", function () { return SL; }); +XPCOMUtils.defineLazyGetter(this, "CP", function () { + let CP = {}; + Cu.import("resource://gre/modules/CpPduHelper.jsm", CP); + return CP; +}); + XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", "@mozilla.org/system-message-internal;1", "nsISystemMessagesInternal"); @@ -92,9 +98,10 @@ this.WapPushManager = { } else if (contentType === "text/vnd.wap.sl" || contentType === "application/vnd.wap.slc") { msg = SL.PduHelper.parse(data, contentType); + } else if (contentType === "text/vnd.wap.connectivity-xml" || + contentType === "application/vnd.wap.connectivity-wbxml") { + msg = CP.PduHelper.parse(data, contentType); } else { - // TODO: Bug 869291 - Support Receiving WAP-Push-CP - // Unsupported type, provide raw data. msg = { contentType: contentType, diff --git a/dom/wappush/src/gonk/WbxmlPduHelper.jsm b/dom/wappush/src/gonk/WbxmlPduHelper.jsm index d625261d33a2..67d231881aa4 100644 --- a/dom/wappush/src/gonk/WbxmlPduHelper.jsm +++ b/dom/wappush/src/gonk/WbxmlPduHelper.jsm @@ -125,27 +125,33 @@ this.PduHelper = { * * @param data * A wrapped object containing raw PDU data. - * @param msg - * Target object for decoding. + * @param decodeInfo + * Information for decoding, now requires charset and string table. * @param appToken * Application-specific token difinition. * * @return Decoded WBXML message string. */ - parseWbxml: function parseWbxml_wbxml(data, msg, appToken) { + parseWbxml: function parseWbxml_wbxml(data, decodeInfo, appToken) { // Parse token definition to my structure. - let tagTokenList = appToken.tagToken; - let attrTokenList = appToken.attrToken; - let globalTokenOverrideList = appToken.globalTokenOverride || {}; + let tagTokenList = appToken.tagTokenList; + let attrTokenList = appToken.attrTokenList; + let valueTokenList = appToken.valueTokenList; - let decodeInfo = { - tagStack: [], // tag decode stack - charset: WSP.WSP_WELL_KNOWN_CHARSETS[msg.charset].converter, // document character set - stringTable: msg.stringTable // document string table - }; + decodeInfo.tagStack = []; // tag decode stack - msg.content = ""; + // Merge global tag tokens into single list, so we don't have + // to search two lists every time. + let globalTagTokenList = Object.create(WBXML_GLOBAL_TOKENS); + if (appToken.globalTokenOverride) { + let globalTokenOverrideList = appToken.globalTokenOverride; + for (let token in globalTokenOverrideList) { + globalTagTokenList[token] = globalTokenOverrideList[token]; + } + } + + let content = ""; while (data.offset < data.array.length) { // Decode content, might be a new tag token, an end of tag token, or an // inline string. @@ -156,21 +162,20 @@ this.PduHelper = { // Try global tag first, tagToken of string table is 0x83, and will be 0x03 // in tagTokenValue, which is collision with inline string. // So tagToken need to be searched before tagTokenValue. - let tagInfo = globalTokenOverrideList[tagToken] || - globalTokenOverrideList[tagTokenValue] || - WBXML_GLOBAL_TOKENS[tagToken] || - WBXML_GLOBAL_TOKENS[tagTokenValue]; + let tagInfo = globalTagTokenList[tagToken] || + globalTagTokenList[tagTokenValue]; if (tagInfo) { - msg.content += tagInfo.coder.decode(data, decodeInfo); + content += tagInfo.coder.decode(data, decodeInfo); continue; } // Check if application tag token is valid tagInfo = tagTokenList[tagTokenValue]; - if (!tagInfo) - continue; + if (!tagInfo) { + throw new Error("Unsupported WBXML token: " + tagTokenValue + "."); + } - msg.content += "<" + tagInfo.name; + content += "<" + tagInfo.name; if (tagToken & TAG_TOKEN_ATTR_MASK) { // Decode attributes, might be a new attribute token, a value token, @@ -183,37 +188,42 @@ this.PduHelper = { break; } - let attrInfo = globalTokenOverrideList[attrToken] || - WBXML_GLOBAL_TOKENS[attrToken]; + let attrInfo = globalTagTokenList[attrToken]; if (attrInfo) { - msg.content += attrInfo.coder.decode(data, decodeInfo); + content += attrInfo.coder.decode(data, decodeInfo); continue; } // Check if attribute token is valid attrInfo = attrTokenList[attrToken]; - if (!attrInfo) - continue; - - if (attrInfo.name !== "") { - msg.content += attrSeperator + " " + attrInfo.name + "=\"" + attrInfo.value; + if (attrInfo) { + content += attrSeperator + " " + attrInfo.name + "=\"" + attrInfo.value; attrSeperator = "\""; - } else { - msg.content += attrInfo.value; + continue; } + + attrInfo = valueTokenList[attrToken]; + if (attrInfo) { + content += attrInfo.value; + continue; + } + + throw new Error("Unsupported WBXML token: " + attrToken + "."); } - msg.content += attrSeperator; + content += attrSeperator; } if (tagToken & TAG_TOKEN_CONTENT_MASK) { - msg.content += ">"; + content += ">"; decodeInfo.tagStack.push(tagInfo); continue; } - msg.content += "/>"; + content += "/>"; } + + return content; }, /** @@ -248,15 +258,11 @@ this.PduHelper = { * decode() returns decoded text, encode() returns * encoded raw data. * } - * @param msg [optional] - * Optional target object for decoding. * * @return A WBXML message object or null in case of errors found. */ - parse: function parse_wbxml(data, appToken, msg) { - if (!msg) { - msg = {}; - } + parse: function parse_wbxml(data, appToken) { + let msg = {}; /** * Read WBXML header. @@ -289,28 +295,19 @@ this.PduHelper = { WSP.WSP_WELL_KNOWN_CHARSETS[msg.charset].converter); } if (msg.publicId != appToken.publicId) { - return null; + throw new Error("Public ID does not match."); } msg.version = ((headerRaw.version >> 4) + 1) + "." + (headerRaw.version & 0x0F); - this.parseWbxml(data, msg, appToken); + let decodeInfo = { + charset: WSP.WSP_WELL_KNOWN_CHARSETS[msg.charset].converter, // document character set + stringTable: msg.stringTable // document string table + }; + msg.content = this.parseWbxml(data, decodeInfo, appToken); return msg; - }, - - /** - * @param multiStream - * An exsiting nsIMultiplexInputStream. - * @param msg - * A SI message object. - * - * @return An instance of nsIMultiplexInputStream or null in case of errors. - */ - compose: function compose_wbxml(multiStream, msg) { - // Composing WBXML message is not supported - return null; - }, + } }; /** diff --git a/dom/wappush/src/moz.build b/dom/wappush/src/moz.build index 4741f907e22d..7a649aed8b58 100644 --- a/dom/wappush/src/moz.build +++ b/dom/wappush/src/moz.build @@ -5,8 +5,9 @@ if CONFIG['MOZ_B2G_RIL']: EXTRA_JS_MODULES = [ + 'gonk/CpPduHelper.jsm', 'gonk/SiPduHelper.jsm', 'gonk/SlPduHelper.jsm', 'gonk/WapPushManager.js', - 'gonk/WbxmlPduHelper.jsm', + 'gonk/WbxmlPduHelper.jsm' ] diff --git a/dom/wappush/tests/test_cp_pdu_helper.js b/dom/wappush/tests/test_cp_pdu_helper.js new file mode 100644 index 000000000000..c43f280eb734 --- /dev/null +++ b/dom/wappush/tests/test_cp_pdu_helper.js @@ -0,0 +1,359 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +let CP = {}; +subscriptLoader.loadSubScript("resource://gre/modules/CpPduHelper.jsm", CP); +CP.debug = do_print; + +function run_test() { + run_next_test(); +} + +function test_parser(rawDataArray, contentType, expectResult) { + let data = { array: rawDataArray, offset: 0 }; + let msg = CP.PduHelper.parse(data, contentType); + do_check_eq(msg.contentType, expectResult.contentType); + do_check_eq(msg.content, expectResult.content); +} + +/* + * Test data from OMA-TS-WAP_ProvCont-V1_1-2009 0421-C.pdf, clause 6.1 + */ +let text_data_array = new Uint8Array([ + 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, + 0x2E, 0x30, 0x22, 0x3F, 0x3E, 0x3C, 0x21, 0x44, + 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x77, + 0x61, 0x70, 0x2D, 0x70, 0x72, 0x6F, 0x76, 0x69, + 0x73, 0x69, 0x6F, 0x6E, 0x69, 0x6E, 0x67, 0x64, + 0x6F, 0x63, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, + 0x43, 0x20, 0x22, 0x2D, 0x2F, 0x2F, 0x57, 0x41, + 0x50, 0x46, 0x4F, 0x52, 0x55, 0x4D, 0x2F, 0x2F, + 0x44, 0x54, 0x44, 0x20, 0x50, 0x52, 0x4F, 0x56, + 0x20, 0x31, 0x2E, 0x30, 0x2F, 0x2F, 0x45, 0x4E, + 0x22, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, + 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x61, + 0x70, 0x66, 0x6F, 0x72, 0x75, 0x6D, 0x2E, 0x6F, + 0x72, 0x67, 0x2F, 0x44, 0x54, 0x44, 0x2F, 0x70, + 0x72, 0x6F, 0x76, 0x2E, 0x64, 0x74, 0x64, 0x22, + 0x3E, 0x3C, 0x77, 0x61, 0x70, 0x2D, 0x70, 0x72, + 0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x69, + 0x6E, 0x67, 0x64, 0x6F, 0x63, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, + 0x2E, 0x30, 0x22, 0x3E, 0x3C, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x50, 0x58, 0x4C, 0x4F, 0x47, 0x49, + 0x43, 0x41, 0x4C, 0x22, 0x3E, 0x3C, 0x70, 0x61, + 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, + 0x22, 0x50, 0x52, 0x4F, 0x58, 0x59, 0x2D, 0x49, + 0x44, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x31, 0x37, 0x30, 0x2E, 0x31, 0x38, + 0x37, 0x2E, 0x35, 0x31, 0x2E, 0x34, 0x22, 0x2F, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x4E, 0x41, 0x4D, + 0x45, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x42, 0x61, 0x6E, 0x6B, 0x4D, 0x61, + 0x69, 0x6E, 0x50, 0x72, 0x6F, 0x78, 0x79, 0x22, + 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, + 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x53, 0x54, + 0x41, 0x52, 0x54, 0x50, 0x41, 0x47, 0x45, 0x22, + 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, + 0x77, 0x77, 0x2E, 0x62, 0x61, 0x6E, 0x6B, 0x2E, + 0x63, 0x6F, 0x6D, 0x2F, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x70, 0x61, 0x67, 0x65, 0x2E, 0x77, 0x6D, + 0x6C, 0x22, 0x2F, 0x3E, 0x3C, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x50, 0x58, 0x41, 0x55, 0x54, 0x48, + 0x49, 0x4E, 0x46, 0x4F, 0x22, 0x3E, 0x3C, 0x70, + 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, + 0x3D, 0x22, 0x50, 0x58, 0x41, 0x55, 0x54, 0x48, + 0x2D, 0x54, 0x59, 0x50, 0x45, 0x22, 0x20, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x48, 0x54, + 0x54, 0x50, 0x2D, 0x42, 0x41, 0x53, 0x49, 0x43, + 0x22, 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x50, + 0x58, 0x41, 0x55, 0x54, 0x48, 0x2D, 0x49, 0x44, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x70, 0x78, 0x75, 0x73, 0x65, 0x72, 0x6E, + 0x61, 0x6D, 0x65, 0x22, 0x2F, 0x3E, 0x3C, 0x70, + 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, + 0x3D, 0x22, 0x50, 0x58, 0x41, 0x55, 0x54, 0x48, + 0x2D, 0x50, 0x57, 0x22, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x70, 0x78, 0x75, 0x73, + 0x65, 0x72, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, + 0x22, 0x2F, 0x3E, 0x3C, 0x2F, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x3E, 0x3C, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x50, 0x58, 0x50, 0x48, 0x59, 0x53, + 0x49, 0x43, 0x41, 0x4C, 0x22, 0x3E, 0x3C, 0x70, + 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, + 0x3D, 0x22, 0x50, 0x48, 0x59, 0x53, 0x49, 0x43, + 0x41, 0x4C, 0x2D, 0x50, 0x52, 0x4F, 0x58, 0x59, + 0x2D, 0x49, 0x44, 0x22, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x50, 0x52, 0x4F, 0x58, + 0x59, 0x20, 0x31, 0x22, 0x2F, 0x3E, 0x3C, 0x70, + 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, + 0x3D, 0x22, 0x44, 0x4F, 0x4D, 0x41, 0x49, 0x4E, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x77, 0x77, 0x77, 0x2E, 0x62, 0x61, 0x6E, + 0x6B, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x22, 0x2F, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x50, 0x58, 0x41, + 0x44, 0x44, 0x52, 0x22, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x31, 0x37, 0x30, 0x2E, + 0x31, 0x38, 0x37, 0x2E, 0x35, 0x31, 0x2E, 0x33, + 0x22, 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x50, + 0x58, 0x41, 0x44, 0x44, 0x52, 0x54, 0x59, 0x50, + 0x45, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x3D, 0x22, 0x49, 0x50, 0x56, 0x34, 0x22, 0x2F, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x54, 0x4F, 0x2D, + 0x4E, 0x41, 0x50, 0x49, 0x44, 0x22, 0x20, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x49, 0x4E, + 0x54, 0x45, 0x52, 0x4E, 0x45, 0x54, 0x22, 0x2F, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x54, 0x4F, 0x2D, + 0x4E, 0x41, 0x50, 0x49, 0x44, 0x22, 0x20, 0x76, + 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4E, 0x41, + 0x50, 0x31, 0x22, 0x2F, 0x3E, 0x3C, 0x63, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3D, 0x22, 0x50, 0x4F, 0x52, 0x54, 0x22, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x50, 0x4F, 0x52, + 0x54, 0x4E, 0x42, 0x52, 0x22, 0x20, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x39, 0x32, 0x30, + 0x33, 0x22, 0x2F, 0x3E, 0x3C, 0x2F, 0x63, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x3E, 0x3C, 0x2F, 0x63, + 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, + 0x69, 0x73, 0x74, 0x69, 0x63, 0x3E, 0x3C, 0x2F, + 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x3E, 0x3C, + 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, + 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3D, 0x22, 0x4E, 0x41, 0x50, + 0x44, 0x45, 0x46, 0x22, 0x3E, 0x3C, 0x70, 0x61, + 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, + 0x22, 0x4E, 0x41, 0x50, 0x49, 0x44, 0x22, 0x20, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x4E, + 0x41, 0x50, 0x31, 0x22, 0x2F, 0x3E, 0x3C, 0x70, + 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, + 0x3D, 0x22, 0x42, 0x45, 0x41, 0x52, 0x45, 0x52, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x47, 0x53, 0x4D, 0x2D, 0x43, 0x53, 0x44, + 0x22, 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x4E, + 0x41, 0x4D, 0x45, 0x22, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x4D, 0x59, 0x20, 0x49, + 0x53, 0x50, 0x20, 0x43, 0x53, 0x44, 0x22, 0x2F, + 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, + 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x4E, 0x41, 0x50, + 0x2D, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x2B, 0x33, 0x35, 0x38, 0x30, 0x38, 0x31, + 0x32, 0x34, 0x30, 0x30, 0x32, 0x22, 0x2F, 0x3E, + 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, + 0x6D, 0x65, 0x3D, 0x22, 0x4E, 0x41, 0x50, 0x2D, + 0x41, 0x44, 0x44, 0x52, 0x54, 0x59, 0x50, 0x45, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x45, 0x31, 0x36, 0x34, 0x22, 0x2F, 0x3E, + 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, + 0x6D, 0x65, 0x3D, 0x22, 0x43, 0x41, 0x4C, 0x4C, + 0x54, 0x59, 0x50, 0x45, 0x22, 0x20, 0x76, 0x61, + 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x41, 0x4E, 0x41, + 0x4C, 0x4F, 0x47, 0x2D, 0x4D, 0x4F, 0x44, 0x45, + 0x4D, 0x22, 0x2F, 0x3E, 0x3C, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3D, 0x22, 0x4E, 0x41, 0x50, 0x41, 0x55, 0x54, + 0x48, 0x49, 0x4E, 0x46, 0x4F, 0x22, 0x3E, 0x3C, + 0x70, 0x61, 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, + 0x65, 0x3D, 0x22, 0x41, 0x55, 0x54, 0x48, 0x54, + 0x59, 0x50, 0x45, 0x22, 0x20, 0x76, 0x61, 0x6C, + 0x75, 0x65, 0x3D, 0x22, 0x50, 0x41, 0x50, 0x22, + 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, 0x20, + 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x41, 0x55, + 0x54, 0x48, 0x4E, 0x41, 0x4D, 0x45, 0x22, 0x20, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x77, + 0x77, 0x77, 0x6D, 0x6D, 0x6D, 0x75, 0x73, 0x65, + 0x72, 0x22, 0x2F, 0x3E, 0x3C, 0x70, 0x61, 0x72, + 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, + 0x41, 0x55, 0x54, 0x48, 0x53, 0x45, 0x43, 0x52, + 0x45, 0x54, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, + 0x65, 0x3D, 0x22, 0x77, 0x77, 0x77, 0x6D, 0x6D, + 0x6D, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, + 0x2F, 0x3E, 0x3C, 0x2F, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, + 0x69, 0x63, 0x3E, 0x3C, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, + 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, + 0x22, 0x56, 0x41, 0x4C, 0x49, 0x44, 0x49, 0x54, + 0x59, 0x22, 0x3E, 0x3C, 0x70, 0x61, 0x72, 0x6D, + 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x43, + 0x4F, 0x55, 0x4E, 0x54, 0x52, 0x59, 0x22, 0x20, + 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x22, 0x32, + 0x32, 0x38, 0x22, 0x2F, 0x3E, 0x3C, 0x70, 0x61, + 0x72, 0x6D, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, + 0x22, 0x4E, 0x45, 0x54, 0x57, 0x4F, 0x52, 0x4B, + 0x22, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, + 0x22, 0x30, 0x30, 0x31, 0x22, 0x2F, 0x3E, 0x3C, + 0x2F, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, 0x3E, + 0x3C, 0x2F, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, + 0x74, 0x65, 0x72, 0x69, 0x73, 0x74, 0x69, 0x63, + 0x3E, 0x3C, 0x2F, 0x77, 0x61, 0x70, 0x2D, 0x70, + 0x72, 0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, + 0x69, 0x6E, 0x67, 0x64, 0x6F, 0x63, 0x3E +]); + +/* + * Test data from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, Appendix C + */ +let wbxml_data_array = new Uint8Array([ + 0x03, 0x0b, 0x6a, 0x05, 0x4e, 0x41, 0x50, 0x31, + 0x00, 0xC5, 0x46, 0x01, 0xc6, 0x51, 0x01, 0x87, + 0x15, 0x06, 0x03, 0x31, 0x37, 0x30, 0x2e, 0x31, + 0x38, 0x37, 0x2e, 0x35, 0x31, 0x2e, 0x34, 0x00, + 0x01, 0x87, 0x07, 0x06, 0x03, 0x42, 0x61, 0x6e, + 0x6b, 0x4d, 0x61, 0x69, 0x6e, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x00, 0x01, 0x87, 0x1c, 0x06, 0x03, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x62, 0x61, 0x6e, 0x6b, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x70, 0x61, 0x67, 0x65, 0x2e, 0x77, 0x6d, + 0x6c, 0x00, 0x01, 0xc6, 0x59, 0x01, 0x87, 0x19, + 0x06, 0x9c, 0x01, 0x87, 0x1a, 0x06, 0x03, 0x70, + 0x78, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x00, 0x01, 0x87, 0x1b, 0x06, 0x03, 0x70, + 0x78, 0x75, 0x73, 0x65, 0x72, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x64, 0x00, 0x01, 0x01, 0xc6, 0x52, + 0x01, 0x87, 0x2f, 0x06, 0x03, 0x50, 0x52, 0x4f, + 0x58, 0x59, 0x20, 0x31, 0x00, 0x01, 0x87, 0x17, + 0x06, 0x03, 0x77, 0x77, 0x77, 0x2e, 0x62, 0x61, + 0x6e, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x00, + 0x01, 0x87, 0x20, 0x06, 0x03, 0x31, 0x37, 0x30, + 0x2e, 0x31, 0x38, 0x37, 0x2e, 0x35, 0x31, 0x2e, + 0x33, 0x00, 0x01, 0x87, 0x21, 0x06, 0x85, 0x01, + 0x87, 0x22, 0x06, 0x03, 0x49, 0x4e, 0x54, 0x45, + 0x52, 0x4e, 0x45, 0x54, 0x00, 0x01, 0x87, 0x22, + 0x06, 0x83, 0x00, 0x01, 0xc6, 0x53, 0x01, 0x87, + 0x23, 0x06, 0x03, 0x39, 0x32, 0x30, 0x33, 0x00, + 0x01, 0x01, 0x01, 0x01, 0xc6, 0x55, 0x01, 0x87, + 0x11, 0x06, 0x83, 0x00, 0x01, 0x87, 0x10, 0x06, + 0xaa, 0x01, 0x87, 0x07, 0x06, 0x03, 0x4d, 0x59, + 0x20, 0x49, 0x53, 0x50, 0x20, 0x43, 0x53, 0x44, + 0x00, 0x01, 0x87, 0x08, 0x06, 0x03, 0x2b, 0x33, + 0x35, 0x38, 0x30, 0x38, 0x31, 0x32, 0x34, 0x30, + 0x30, 0x32, 0x00, 0x01, 0x87, 0x09, 0x06, 0x87, + 0x01, 0x87, 0x0a, 0x06, 0x90, 0x01, 0xc6, 0x5a, + 0x01, 0x87, 0x0c, 0x06, 0x9a, 0x01, 0x87, 0x0d, + 0x06, 0x03, 0x77, 0x77, 0x77, 0x6d, 0x6d, 0x6d, + 0x75, 0x73, 0x65, 0x72, 0x00, 0x01, 0x87, 0x0e, + 0x06, 0x03, 0x77, 0x77, 0x77, 0x6d, 0x6d, 0x6d, + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x01, + 0x01, 0xc6, 0x54, 0x01, 0x87, 0x12, 0x06, 0x03, + 0x32, 0x32, 0x38, 0x00, 0x01, 0x87, 0x13, 0x06, + 0x03, 0x30, 0x30, 0x31, 0x00, 0x01, 0x01, 0x01, + 0x01 +]); + +/* + * Test data from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, clause 6.1 + */ +let xml_header = + "" + + ""; + +let xml_body = + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + +/** + * CP in plain text + * + * Test case from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, clause 6.1 + */ +add_test(function test_cp_parse_plain_text() { + test_parser(text_data_array, "text/vnd.wap.connectivity-xml", { + contentType: "text/vnd.wap.connectivity-xml", + content: xml_header + xml_body + }); + + run_next_test(); +}); + +/** + * CP compressed by WBXML + * + * Test case from OMA-TS-WAP_ProvCont-V1_1-20090421-C.pdf, Appendix C + */ +add_test(function test_cp_parse_wbxml() { + test_parser(wbxml_data_array, "application/vnd.wap.connectivity-wbxml", { + contentType: "text/vnd.wap.connectivity-xml", + content: xml_body + }); + + run_next_test(); +}); + +/** + * CP compressed by WBXML with VENDORCONFIG + */ +add_test(function test_cp_parse_wbxml() { + let wbxml_vendor_config_data_array = new Uint8Array([ + 0x03, 0x0b, 0x6a, 0x05, 0x4e, 0x41, 0x50, 0x31, + 0x00, 0xC5, 0x46, 0x01, 0xc6, 0x57, 0x01, 0x01 + ]); + + test_parser(wbxml_vendor_config_data_array, "application/vnd.wap.connectivity-wbxml", { + contentType: "application/vnd.wap.connectivity-wbxml", + content: wbxml_vendor_config_data_array + }); + + run_next_test(); +}); diff --git a/dom/wappush/tests/xpcshell.ini b/dom/wappush/tests/xpcshell.ini index 03cbd59d605e..253de8c0554d 100644 --- a/dom/wappush/tests/xpcshell.ini +++ b/dom/wappush/tests/xpcshell.ini @@ -4,3 +4,4 @@ tail = [test_si_pdu_helper.js] [test_sl_pdu_helper.js] +[test_cp_pdu_helper.js] diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 49e84414fbf0..50776b667cf9 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -272,20 +272,22 @@ AsyncPanZoomController::ReceiveInputEvent(const nsInputEvent& aEvent, for (uint32_t i = 0; i < touches.Length(); ++i) { nsIDOMTouch* touch = touches[i]; if (touch) { - CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace( + CSSPoint refCSSPoint = WidgetSpaceToCompensatedViewportSpace( ScreenPoint::FromUnknownPoint(gfx::Point( touch->mRefPoint.x, touch->mRefPoint.y)), currentResolution); + LayoutDevicePoint refPoint = refCSSPoint * mFrameMetrics.mDevPixelsPerCSSPixel; touch->mRefPoint = nsIntPoint(refPoint.x, refPoint.y); } } break; } default: { - CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace( + CSSPoint refCSSPoint = WidgetSpaceToCompensatedViewportSpace( ScreenPoint::FromUnknownPoint(gfx::Point( aOutEvent->refPoint.x, aOutEvent->refPoint.y)), currentResolution); + LayoutDevicePoint refPoint = refCSSPoint * mFrameMetrics.mDevPixelsPerCSSPixel; aOutEvent->refPoint = nsIntPoint(refPoint.x, refPoint.y); break; } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 0f1fb69392f8..5f08d9acd945 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1500,7 +1500,7 @@ nsDisplayItem::ForceActiveLayers() /* static */ int32_t nsDisplayItem::MaxActiveLayers() { - static int32_t sMaxLayers = false; + static int32_t sMaxLayers = -1; static bool sMaxLayersCached = false; if (!sMaxLayersCached) { @@ -1508,7 +1508,7 @@ nsDisplayItem::MaxActiveLayers() sMaxLayersCached = true; } - return sMaxLayersCached; + return sMaxLayers; } bool diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index ba8b4b5ba4ec..1fb67d4ecf7f 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -551,7 +551,7 @@ pref("layers.low-precision-resolution", 250); // 2) Pages that have too many layers consume too much memory and crash. // By limiting the number of layers on mobile we're making the main thread // work harder keep scrolling smooth and memory low. -pref("layers.max-active", 20); +pref("layers.max-active", 1); pref("notification.feature.enabled", true); pref("dom.webnotifications.enabled", true); diff --git a/netwerk/base/public/nsIBrowserSearchService.idl b/netwerk/base/public/nsIBrowserSearchService.idl index 726a64a0333d..6860e88d004f 100644 --- a/netwerk/base/public/nsIBrowserSearchService.idl +++ b/netwerk/base/public/nsIBrowserSearchService.idl @@ -7,7 +7,7 @@ interface nsIURI; interface nsIInputStream; -[scriptable, uuid(58e4f602-a7c8-4cd1-9dca-716705e826ef)] +[scriptable, uuid(82ec6ee8-68b5-49ef-87b7-0d5240f8a183)] interface nsISearchSubmission : nsISupports { /** @@ -16,6 +16,12 @@ interface nsISearchSubmission : nsISupports */ readonly attribute nsIInputStream postData; + /** + * The POST data associated with a search submission as an + * application/x-www-form-urlencoded string. May be null. + */ + readonly attribute AString postDataString; + /** * The URI to submit a search to. */ diff --git a/toolkit/components/search/nsSearchService.js b/toolkit/components/search/nsSearchService.js index 6f1e6a0981df..b746de3714a2 100644 --- a/toolkit/components/search/nsSearchService.js +++ b/toolkit/components/search/nsSearchService.js @@ -931,6 +931,7 @@ EngineURL.prototype = { } var postData = null; + let postDataString = null; if (this.method == "GET") { // GET method requests have no post data, and append the encoded // query string to the url... @@ -938,8 +939,8 @@ EngineURL.prototype = { url += "?"; url += dataString; } else if (this.method == "POST") { - // POST method requests must wrap the encoded text in a MIME - // stream and supply that as POSTDATA. + // For POST requests, specify the data as a MIME stream as well as a string. + postDataString = dataString; var stringStream = Cc["@mozilla.org/io/string-input-stream;1"]. createInstance(Ci.nsIStringInputStream); stringStream.data = dataString; @@ -951,7 +952,7 @@ EngineURL.prototype = { postData.setData(stringStream); } - return new Submission(makeURI(url), postData); + return new Submission(makeURI(url), postData, postDataString); }, _hasRelation: function SRC_EURL__hasRelation(aRel) @@ -2543,7 +2544,7 @@ Engine.prototype = { if (!aData) { // Return a dummy submission object with our searchForm attribute - return new Submission(makeURI(this.searchForm), null); + return new Submission(makeURI(this.searchForm)); } LOG("getSubmission: In data: \"" + aData + "\"; Purpose: \"" + aPurpose + "\""); @@ -2580,9 +2581,10 @@ Engine.prototype = { }; // nsISearchSubmission -function Submission(aURI, aPostData) { +function Submission(aURI, aPostData = null, aPostDataString = null) { this._uri = aURI; this._postData = aPostData; + this._postDataString = aPostDataString; } Submission.prototype = { get uri() { @@ -2591,6 +2593,9 @@ Submission.prototype = { get postData() { return this._postData; }, + get postDataString() { + return this._postDataString; + }, QueryInterface: function SRCH_SUBM_QI(aIID) { if (aIID.equals(Ci.nsISearchSubmission) || aIID.equals(Ci.nsISupports)) diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js index d00d90742027..6c97c238495c 100644 --- a/toolkit/mozapps/update/nsUpdateService.js +++ b/toolkit/mozapps/update/nsUpdateService.js @@ -4329,6 +4329,13 @@ Downloader.prototype = { this._update.statusText = getStatusTextFromCode(status, Cr.NS_BINDING_FAILED); +#ifdef MOZ_WIDGET_GONK + // bug891009: On FirefoxOS, manaully retry OTA download will reuse + // the Update object. We need to remove selected patch so that download + // can be triggered again successfully. + this._update.selectedPatch.selected = false; +#endif + // Destroy the updates directory, since we're done with it. cleanUpUpdatesDir();