summaryrefslogtreecommitdiffstats
path: root/b2g/components/SimulatorScreen.js
diff options
context:
space:
mode:
Diffstat (limited to 'b2g/components/SimulatorScreen.js')
-rw-r--r--b2g/components/SimulatorScreen.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/b2g/components/SimulatorScreen.js b/b2g/components/SimulatorScreen.js
new file mode 100644
index 000000000..18d8f5cc4
--- /dev/null
+++ b/b2g/components/SimulatorScreen.js
@@ -0,0 +1,117 @@
+/* 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/. */
+
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://gre/modules/DOMRequestHelper.jsm');
+
+XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen',
+ 'resource://gre/modules/GlobalSimulatorScreen.jsm');
+
+var DEBUG_PREFIX = 'SimulatorScreen.js - ';
+function debug() {
+ //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n');
+}
+
+function fireOrientationEvent(window) {
+ let e = new window.Event('mozorientationchange');
+ window.screen.dispatchEvent(e);
+}
+
+function hookScreen(window) {
+ let nodePrincipal = window.document.nodePrincipal;
+ let origin = nodePrincipal.origin;
+ if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
+ // Only inject screen mock for apps
+ return;
+ }
+
+ let screen = window.wrappedJSObject.screen;
+
+ screen.mozLockOrientation = function (orientation) {
+ debug('mozLockOrientation:', orientation, 'from', origin);
+
+ // Normalize and do some checks against orientation input
+ if (typeof(orientation) == 'string') {
+ orientation = [orientation];
+ }
+
+ function isInvalidOrientationString(str) {
+ return typeof(str) != 'string' ||
+ !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/);
+ }
+ if (!Array.isArray(orientation) ||
+ orientation.some(isInvalidOrientationString)) {
+ Cu.reportError('Invalid orientation "' + orientation + '"');
+ return false;
+ }
+
+ GlobalSimulatorScreen.lock(orientation);
+
+ return true;
+ };
+
+ screen.mozUnlockOrientation = function() {
+ debug('mozOrientationUnlock from', origin);
+ GlobalSimulatorScreen.unlock();
+ return true;
+ };
+
+ Object.defineProperty(screen, 'width', {
+ get: () => GlobalSimulatorScreen.width
+ });
+ Object.defineProperty(screen, 'height', {
+ get: () => GlobalSimulatorScreen.height
+ });
+ Object.defineProperty(screen, 'mozOrientation', {
+ get: () => GlobalSimulatorScreen.mozOrientation
+ });
+}
+
+function SimulatorScreen() {}
+SimulatorScreen.prototype = {
+ classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference]),
+ _windows: new Map(),
+
+ observe: function (subject, topic, data) {
+ let windows = this._windows;
+ switch (topic) {
+ case 'profile-after-change':
+ Services.obs.addObserver(this, 'document-element-inserted', false);
+ Services.obs.addObserver(this, 'simulator-orientation-change', false);
+ Services.obs.addObserver(this, 'inner-window-destroyed', false);
+ break;
+
+ case 'document-element-inserted':
+ let window = subject.defaultView;
+ if (!window) {
+ return;
+ }
+
+ hookScreen(window);
+
+ var id = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .currentInnerWindowID;
+ windows.set(id, window);
+ break;
+
+ case 'inner-window-destroyed':
+ var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
+ windows.delete(id);
+ break;
+
+ case 'simulator-orientation-change':
+ windows.forEach(fireOrientationEvent);
+ break;
+ }
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]);