Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
290 lines
8.7 KiB
JavaScript
290 lines
8.7 KiB
JavaScript
/* globals LockScreenAgent, LazyLoader */
|
|
/* global Service */
|
|
'use strict';
|
|
|
|
(function(exports) {
|
|
var AppWindow = window.AppWindow;
|
|
|
|
/**
|
|
* This window is inherit the AppWindow, and modifies some properties
|
|
* different from the later.
|
|
*
|
|
* @constructor LockScreenWindow
|
|
* @augments AppWindow
|
|
*/
|
|
var LockScreenWindow = function() {
|
|
// Before we make lockscreen as an app (Bug 898348 ), which would
|
|
// own its own manifest, we must mock a manifest for him.
|
|
this.configs = {
|
|
url: window.location.href,
|
|
manifest: {
|
|
orientation: ['default']
|
|
},
|
|
name: 'Lockscreen',
|
|
// No manifestURL + no chrome would cause a default chrome app
|
|
manifestURL: window.location.href.replace('system', 'lockscreen') +
|
|
'/manifest.webapp',
|
|
origin: window.location.origin.replace('system', 'lockscreen'),
|
|
inputWindow: {
|
|
resizeMode: false
|
|
}
|
|
};
|
|
this.iframe = this.createFrame();
|
|
if (!this.iframe || !this.iframe.parentNode) {
|
|
// XXX: Lockscreen DOM elements are not copied.
|
|
return;
|
|
}
|
|
|
|
LazyLoader.load(['js/lockscreen_agent.js']).then(() => {
|
|
this.lockScreenAgent = new LockScreenAgent(this.iframe);
|
|
this.lockScreenAgent.start();
|
|
}).catch((err) => {
|
|
console.error(err);
|
|
});
|
|
AppWindow.call(this, this.configs);
|
|
window.dispatchEvent(new CustomEvent('lockscreen-frame-bootstrap', {
|
|
detail: this
|
|
}));
|
|
};
|
|
|
|
/**
|
|
* @borrows AppWindow.prototype as LockScreenWindow.prototype
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype = Object.create(AppWindow.prototype);
|
|
|
|
LockScreenWindow.prototype.constructor = LockScreenWindow;
|
|
|
|
LockScreenWindow.prototype.isLockscreen = true;
|
|
|
|
LockScreenWindow.SUB_COMPONENTS = {
|
|
'transitionController': 'AppTransitionController',
|
|
'statusbar': 'AppStatusbar'
|
|
};
|
|
|
|
LockScreenWindow.REGISTERED_EVENTS = AppWindow.REGISTERED_EVENTS;
|
|
|
|
/**
|
|
* We still need this before we put the lockreen inside an iframe.
|
|
*
|
|
* @type LockScreen
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.lockscreen = null;
|
|
|
|
LockScreenWindow.prototype.HIERARCHY_MANAGER = 'LockScreenWindowManager';
|
|
|
|
/**
|
|
* We would maintain our own events by other components.
|
|
*
|
|
* @type string
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.eventPrefix = 'lockscreen-app';
|
|
|
|
/**
|
|
* Different animation from the original window.
|
|
*
|
|
* @type string
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.openAnimation = 'immediate';
|
|
|
|
/**
|
|
* Different animation from the original window.
|
|
*
|
|
* @type string
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.closeAnimation = 'fade-out';
|
|
|
|
LockScreenWindow.prototype._DEBUG = false;
|
|
|
|
/**
|
|
* LockScreenWindow has its own styles.
|
|
*
|
|
* @type string
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.CLASS_LIST = 'appWindow lockScreenWindow';
|
|
LockScreenWindow.prototype.CLASS_NAME = 'LockScreenWindow';
|
|
|
|
LockScreenWindow.prototype._resize = function aw__resize() {
|
|
var height, width;
|
|
|
|
// We want the lockscreen to go below the Statusbar
|
|
height = Service.query('LayoutManager.height') || window.innerHeight;
|
|
width = Service.query('LayoutManager.width') || window.innerWidth;
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
this.element.style.width = this.width + 'px';
|
|
this.element.style.height = this.height + 'px';
|
|
|
|
this.resized = true;
|
|
|
|
/**
|
|
* Fired when the app is resized.
|
|
*
|
|
* @event LockScreenWindow#lockscreen-appresize
|
|
*/
|
|
this.publish('resize');
|
|
};
|
|
|
|
/**
|
|
* Create the iframe and load it.
|
|
*
|
|
* @this {LockScreenWindow}
|
|
* @memberof LockScreenWindow
|
|
*/
|
|
LockScreenWindow.prototype.createFrame =
|
|
function lsw_createFrame() {
|
|
// XXX: Before we can make LockScreen as a real app,
|
|
// we need these.
|
|
var frame = document.getElementById('lockscreen-frame');
|
|
if (!frame) {
|
|
// XXX: This means we failed to build the system app.
|
|
// So from now on we will try to go without lockscreen.
|
|
frame = document.createElement('div');
|
|
}
|
|
frame.setVisible = function() {};
|
|
// XXX: real mozbrowser iframes would own these methods.
|
|
frame.addNextPaintListener = function(cb) {
|
|
cb();
|
|
};
|
|
frame.removeNextPaintListener = function() {};
|
|
frame.getScreenshot = function() {
|
|
// Mock the request.
|
|
return {
|
|
get onsuccess() {return null;},
|
|
set onsuccess(cb) {
|
|
var mockEvent = {
|
|
target: {result: null}
|
|
};
|
|
cb(mockEvent);
|
|
}
|
|
};
|
|
};
|
|
frame.removeAttribute('hidden');
|
|
return frame;
|
|
};
|
|
|
|
LockScreenWindow.prototype.getNotificationContainer =
|
|
function lsw_getNotificationContainer() {
|
|
// XXX: After we make LockScreen as an app, needn't this anymore.
|
|
return document.getElementById(
|
|
'notifications-lockscreen-container');
|
|
};
|
|
|
|
LockScreenWindow.prototype._resize =
|
|
function lsw__resize() {
|
|
var height, width;
|
|
this.debug('force RESIZE...');
|
|
if (this.inputWindow && typeof this.inputWindow.isActive === 'function' &&
|
|
this.inputWindow.isActive()) {
|
|
/**
|
|
* The event is dispatched on the app window only when keyboard is up.
|
|
*
|
|
* @access private
|
|
* @event LockScreenWindow~_withkeyboard
|
|
*/
|
|
this.broadcast('withkeyboard');
|
|
} else {
|
|
/**
|
|
* The event is dispatched on the LockScreen window only
|
|
* when keyboard is hidden.
|
|
*
|
|
* @access private
|
|
* @event LockScreenWindow~_withoutkeyboard
|
|
*/
|
|
this.broadcast('withoutkeyboard');
|
|
}
|
|
height = this.layoutHeight();
|
|
width = this.layoutWidth();
|
|
|
|
this.width = width;
|
|
this.height = height;
|
|
this.element.style.width = this.width + 'px';
|
|
this.element.style.height = this.height + 'px';
|
|
|
|
this.browser.element.style.width = '';
|
|
this.browser.element.style.height = '';
|
|
|
|
this.resized = true;
|
|
if (this.screenshotOverlay) {
|
|
this.screenshotOverlay.style.visibility = '';
|
|
}
|
|
|
|
/**
|
|
* Fired when the app is resized.
|
|
*
|
|
* @event LockScreenWindow#lockscreen-appresize
|
|
*/
|
|
this.publish('resize');
|
|
this.debug('W:', this.width, 'H:', this.height);
|
|
};
|
|
|
|
// XXX Bug 1085226: Before we make LockScreen use real keyboard, we need this.
|
|
LockScreenWindow.prototype.layoutHeight =
|
|
function lwm_layoutHeight() {
|
|
// Whether we can resize or not (depends on if the content
|
|
// is inside an iframe or not).
|
|
if (!this.configs.inputWindow.resizeMode) {
|
|
return window.innerHeight;
|
|
}
|
|
var softwareButtonHeight = this.isActive() ?
|
|
0 : (Service.query('SoftwareButtonManager.height') || 0);
|
|
var inputWindowHeight = 0;
|
|
if (this.states.instance && this.states.instance.inputWindow &&
|
|
typeof this.states.instance.inputWindow.isActive === 'function' &&
|
|
this.states.instance.inputWindow.isActive()) {
|
|
inputWindowHeight = this.configs.inputWindow.height;
|
|
}
|
|
var height = window.innerHeight -
|
|
inputWindowHeight -
|
|
softwareButtonHeight;
|
|
|
|
// Normalizing the height so that it always translates to an integral
|
|
// number of device pixels
|
|
var dpx = window.devicePixelRatio;
|
|
if ((height * dpx) % 1 !== 0) {
|
|
height = Math.ceil(height * dpx) / dpx;
|
|
}
|
|
|
|
return height;
|
|
};
|
|
|
|
LockScreenWindow.prototype.layoutWidth =
|
|
function() {
|
|
return window.innerWidth;
|
|
};
|
|
|
|
LockScreenWindow.prototype.lockOrientation =
|
|
function() {
|
|
// XXX: When we turn the screen on, try to lock the orientation
|
|
// until it works. It may fail at the moment the screenchange
|
|
// event has been fired, so we may need to try it several times.
|
|
var tryLockOrientation = () => {
|
|
if (screen.mozLockOrientation('portrait-primary')) {
|
|
if (!this.orientationLockID) {
|
|
throw new Error('No orientation ID. This function should only' +
|
|
'be invoked as a interval callback');
|
|
}
|
|
window.clearInterval(this.orientationLockID);
|
|
this.orientationLockID = null;
|
|
}
|
|
};
|
|
if (Service.query('isOnRealDevice')) {
|
|
if (this.orientationLockID) {
|
|
// The previous one still present and was not cleared,
|
|
// so do nothing.
|
|
return;
|
|
}
|
|
this.orientationLockID =
|
|
window.setInterval(tryLockOrientation, 4);
|
|
// 4ms is the minimum interval according to W3C#setTimeout standard.
|
|
}
|
|
};
|
|
|
|
exports.LockScreenWindow = LockScreenWindow;
|
|
})(window);
|