Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[embedlite-components] Send content orientation changed message to ch…
…rome. Fixes JB#35447 Send "embed:contentOrientationChanged" message to chrome after content has been resized after orientation change. Changing orientation between mirrored orientations (primary to secondary or other way round) is cheap and does not trigger reflow. Thus, those can be send back to chrome immediately. There is a 200ms fallback timer that guarantees that we send the orientation change eventually. Noticed for instance that full screen video playback orientation change did not always trigger resizing while it should have been triggered. This is inspited by B2G's OrientationChangeHandler.jsm.
- Loading branch information
Showing
6 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* 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/. */ | ||
|
||
const Cc = Components.classes; | ||
const Ci = Components.interfaces; | ||
const Cr = Components.results; | ||
const Cu = Components.utils; | ||
|
||
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | ||
Cu.import("resource://gre/modules/Services.jsm"); | ||
Cu.import("chrome://embedlite/content/OrientationChangeHandler.jsm") | ||
|
||
XPCOMUtils.defineLazyServiceGetter(Services, "embedlite", | ||
"@mozilla.org/embedlite-app-service;1", | ||
"nsIEmbedAppService"); | ||
|
||
function EmbedLiteOrientationChangeHandler() | ||
{ | ||
} | ||
|
||
EmbedLiteOrientationChangeHandler.prototype = { | ||
classID: Components.ID("{39c15bb1-0a5c-42ff-979a-f2cfd966743c}"), | ||
_orientationListeners: {}, | ||
|
||
_initialize: function() { | ||
Services.obs.addObserver(this, "embedliteviewcreated", true); | ||
Services.obs.addObserver(this, "domwindowclosed", true); | ||
}, | ||
|
||
observe: function(aSubject, aTopic, aData) { | ||
let self = this; | ||
switch (aTopic) { | ||
case "app-startup": { | ||
self._initialize(); | ||
break; | ||
} | ||
|
||
case "embedliteviewcreated": { | ||
self.onWindowOpen(aSubject); | ||
break; | ||
} | ||
case "domwindowclosed": { | ||
self.onWindowClosed(aSubject); | ||
break; | ||
} | ||
} | ||
}, | ||
|
||
onWindowOpen: function(aWindow) { | ||
this._orientationListeners[aWindow] = new OrientationChangeHandler(aWindow); | ||
Services.embedlite.chromeEventHandler(aWindow).addEventListener("DOMContentLoaded", this._orientationListeners[aWindow], false); | ||
}, | ||
|
||
onWindowClosed: function(aWindow) { | ||
Services.embedlite.chromeEventHandler(aWindow).addEventListener("DOMContentLoaded", this._orientationListeners[aWindow], false); | ||
delete this._orientationListeners[aWindow]; | ||
}, | ||
|
||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]) | ||
}; | ||
|
||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EmbedLiteOrientationChangeHandler]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* 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"; | ||
|
||
this.EXPORTED_SYMBOLS = ["OrientationChangeHandler"]; | ||
|
||
const Ci = Components.interfaces; | ||
const Cu = Components.utils; | ||
|
||
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | ||
Cu.import("resource://gre/modules/Services.jsm"); | ||
|
||
XPCOMUtils.defineLazyServiceGetter(Services, "embedlite", | ||
"@mozilla.org/embedlite-app-service;1", | ||
"nsIEmbedAppService"); | ||
|
||
this.OrientationChangeHandler = function OrientationChangeHandler(window) { | ||
this._winID = Services.embedlite.getIDByWindow(window); | ||
this._targetWindow = Services.embedlite.getContentWindowByID(this._winID); | ||
// "DomContentLoaded" event listener registered in EmbedLiteOrientationChangeHandler.js | ||
} | ||
|
||
OrientationChangeHandler.prototype = { | ||
_targetWindow: null, | ||
_winID: -1, | ||
|
||
lastOrientation: "portrait-primary", | ||
isRegistered: false, | ||
|
||
handleOrientationChange: function(evt) { | ||
let that = this; | ||
let newOrientation = that._targetWindow.screen.mozOrientation; | ||
let fullSwitch = (newOrientation.split("-")[0] == | ||
that.lastOrientation.split("-")[0]); | ||
let changeSent = false; | ||
that.lastOrientation = newOrientation; | ||
|
||
function sendOrientationChanged() { | ||
if (changeSent) { | ||
return; | ||
} | ||
try { | ||
Services.embedlite.sendAsyncMessage(that._winID, "embed:contentOrientationChanged", | ||
JSON.stringify({ | ||
"orientation": newOrientation | ||
})); | ||
changeSent = true; | ||
} catch (e) { | ||
dump("EmbedLiteOrientationChangeHandler: Failed to report orientation change " + e + "\n") | ||
} | ||
} | ||
|
||
// 180deg rotation, no resize | ||
if (fullSwitch) { | ||
that._targetWindow.setTimeout(sendOrientationChanged); | ||
return; | ||
} | ||
|
||
that._targetWindow.addEventListener("resize", resizeThrottler, false); | ||
let resizeTimeout; | ||
function resizeThrottler() { | ||
// ignore resize events as long as an actualResizeHandler execution is in the queue | ||
if (!resizeTimeout) { | ||
resizeTimeout = that._targetWindow.setTimeout(function() { | ||
resizeTimeout = null; | ||
that._targetWindow.removeEventListener("resize", resizeThrottler, false); | ||
sendOrientationChanged(); | ||
|
||
// The sendOrientationChanged will execute at a rate of 15fps | ||
// Noise should be small as we're only listening resizing after | ||
// orientation has changed. | ||
}, 66); | ||
} | ||
} | ||
|
||
// Fallback timeout 200ms. | ||
// When fullscreen video playback is running, noticed that | ||
// resizing doesn't take always place. This guarantees that | ||
// we will send the message back to chrome after 200ms. Normally | ||
// we go always through the resizeThrottler. | ||
that._targetWindow.setTimeout(sendOrientationChanged, 200); | ||
}, | ||
|
||
handleEvent: function(evt) { | ||
let window = this._targetWindow; | ||
switch (evt.type) { | ||
case "DOMContentLoaded": | ||
let target = evt.originalTarget; | ||
// ignore on frames and other documents | ||
if (target != window.document) { | ||
return; | ||
} | ||
|
||
if (!this.isRegistered) { | ||
window.screen.addEventListener("mozorientationchange", this, true); | ||
// This will take care of navigation between pages. | ||
window.addEventListener("beforeunload", this, true); | ||
this.isRegistered = true; | ||
} | ||
|
||
// Confirm initial orientation | ||
try { | ||
this.lastOrientation = this._targetWindow.screen.mozOrientation; | ||
Services.embedlite.sendAsyncMessage(this._winID, "embed:contentOrientationChanged", | ||
JSON.stringify({ | ||
"orientation": this.lastOrientation | ||
})); | ||
} catch (e) { | ||
dump("EmbedLiteOrientationChangeHandler: Report initial orientation " + e + "\n") | ||
} | ||
|
||
|
||
break; | ||
case "mozorientationchange": | ||
this.handleOrientationChange(evt); | ||
break; | ||
case "beforeunload": | ||
if (window && window.screen) { | ||
window.screen.removeEventListener("mozorientationchange", this, true); | ||
} | ||
this.isRegistered = false; | ||
break; | ||
} | ||
}, | ||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener, Ci.nsISupportsWeakReference]) | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters