From c25109716925537e6b5fa4ef5cae237a35a9cb1d Mon Sep 17 00:00:00 2001 From: Tim Chien Date: Mon, 28 Sep 2015 09:27:49 -0700 Subject: [PATCH] Bug 1160923 - [B2G] Waiting for explicit mozContentEvent before sending out mozChromeEvents, r=vingtetun, f=ochaumeau --- b2g/chrome/content/devtools/hud.js | 11 +- b2g/chrome/content/shell.js | 111 +++++++++++------- b2g/components/SystemAppProxy.jsm | 53 ++++++++- .../test/mochitest/systemapp_helper.js | 48 ++++++-- .../NetworkPreparationChromeScript.js | 3 - testing/mochitest/b2g_start_script.js | 3 + 6 files changed, 157 insertions(+), 72 deletions(-) diff --git a/b2g/chrome/content/devtools/hud.js b/b2g/chrome/content/devtools/hud.js index 3836e7e75547..6ca5ee297d39 100644 --- a/b2g/chrome/content/devtools/hud.js +++ b/b2g/chrome/content/devtools/hud.js @@ -190,7 +190,7 @@ var developerHUD = { * metrics, and how to notify the front-end when metrics have changed. */ function Target(frame, actor) { - this._frame = frame; + this.frame = frame; this.actor = actor; this.metrics = new Map(); this._appName = null; @@ -198,15 +198,8 @@ function Target(frame, actor) { Target.prototype = { - get frame() { - let frame = this._frame; - let systemapp = document.querySelector('#systemapp'); - - return (frame === systemapp ? getContentWindow() : frame); - }, - get manifest() { - return this._frame.appManifestURL; + return this.frame.appManifestURL; }, get appName() { diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index e4c6fdec951d..7d39f4939bb9 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -82,10 +82,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SafeMode", window.performance.measure('gecko-shell-jsm-loaded', 'gecko-shell-loadstart'); -function getContentWindow() { - return shell.contentBrowser.contentWindow; -} - function debug(str) { dump(' -*- Shell.js: ' + str + '\n'); } @@ -388,7 +384,7 @@ var shell = { CaptivePortalLoginHelper.init(); this.contentBrowser.src = homeURL; - this.isHomeLoaded = false; + this._isEventListenerReady = false; window.performance.mark('gecko-shell-system-frame-set'); @@ -480,6 +476,13 @@ var shell = { this.contentBrowser.setVisible(true); } break; + case 'load': + if (content.document.location == 'about:blank') { + return; + } + content.removeEventListener('load', this, true); + this.notifyContentWindowLoaded(); + break; case 'mozbrowserloadstart': if (content.document.location == 'about:blank') { this.contentBrowser.addEventListener('mozbrowserlocationchange', this, true); @@ -586,9 +589,12 @@ var shell = { break; case 'MozAfterPaint': window.removeEventListener('MozAfterPaint', this); - this.sendChromeEvent({ + // This event should be sent before System app returns with + // system-message-listener-ready mozContentEvent, because it's on + // the critical launch path of the app. + SystemAppProxy._sendCustomEvent('mozChromeEvent', { type: 'system-first-paint' - }); + }, /* noPending */ true); break; case 'unload': this.stop(); @@ -610,6 +616,14 @@ var shell = { // Send an event to a specific window, document or element. sendEvent: function shell_sendEvent(target, type, details) { + if (target === this.contentBrowser) { + // We must ask SystemAppProxy to send the event in this case so + // that event would be dispatched from frame.contentWindow instead of + // on the System app frame. + SystemAppProxy._sendCustomEvent(type, details); + return; + } + let doc = target.document || target.ownerDocument || target; let event = doc.createEvent('CustomEvent'); event.initCustomEvent(type, true, true, details ? details : {}); @@ -617,21 +631,10 @@ var shell = { }, sendCustomEvent: function shell_sendCustomEvent(type, details) { - let target = getContentWindow(); - let payload = details ? Cu.cloneInto(details, target) : {}; - this.sendEvent(target, type, payload); + SystemAppProxy._sendCustomEvent(type, details); }, sendChromeEvent: function shell_sendChromeEvent(details) { - if (!this.isHomeLoaded) { - if (!('pendingChromeEvents' in this)) { - this.pendingChromeEvents = []; - } - - this.pendingChromeEvents.push(details); - return; - } - this.sendCustomEvent("mozChromeEvent", details); }, @@ -672,6 +675,7 @@ var shell = { this.contentBrowser.removeEventListener('mozbrowserlocationchange', this, true); let content = this.contentBrowser.contentWindow; + content.addEventListener('load', this, true); this.reportCrash(true); @@ -685,28 +689,7 @@ var shell = { Cu.import('resource://gre/modules/OperatorApps.jsm'); #endif - content.addEventListener('load', function shell_homeLoaded() { - content.removeEventListener('load', shell_homeLoaded); - shell.isHomeLoaded = true; - - if (Services.prefs.getBoolPref('b2g.orientation.animate')) { - Cu.import('resource://gre/modules/OrientationChangeHandler.jsm'); - } - -#ifdef MOZ_WIDGET_GONK - libcutils.property_set('sys.boot_completed', '1'); -#endif - - Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); - - SystemAppProxy.setIsReady(); - if ('pendingChromeEvents' in shell) { - shell.pendingChromeEvents.forEach((shell.sendChromeEvent).bind(shell)); - } - delete shell.pendingChromeEvents; - }); - - shell.handleCmdLine(); + this.handleCmdLine(); }, handleCmdLine: function shell_handleCmdLine() { @@ -727,6 +710,38 @@ var shell = { } #endif }, + + // This gets called when window.onload fires on the System app content window, + // which means things in are parsed and statically referenced