/* global SettingsListener, Service */
'use strict';
(function(exports) {
/**
* OrientationManager manages the orientation.
*
*
* There're some cases we need to reset the orientation of the top window:
* * LockScreen is unlocked.
* * An attention window is opened.
* * All attention window is closed.
* * TrustedUI is closed.
* * sleepMenu is hidden.
*
* Any of them occurs would trigger OrientationManager to dispatch
* <code>reset-orientation</code> event and AppWindowManager would reset the
* orientation of the active window.
*
* ![Change orientation flow](http://i.imgur.com/KCUgFH6.png)
*
* @module OrientationManager
*/
var OrientationManager = {
name: 'OrientationManager',
start: function() {
this.fetchDefaultOrientation();
if (SettingsListener) {
SettingsListener.observe('screen.orientation.lock', false,
function(value) {
this.globalOrientation = value ?
this.fetchCurrentOrientation() : null;
this.publish('reset-orientation');
}.bind(this));
}
window.addEventListener('lockscreen-appclosing', this);
window.addEventListener('attentionclosed', this);
window.addEventListener('sleepmenuhide', this);
window.addEventListener('trusteduiclose', this);
window.addEventListener('shrinking-stop', this);
window.addEventListener('searchclosing', this);
Service.registerState('globalOrientation', this);
Service.registerState('defaultOrientation', this);
Service.registerState('fetchCurrentOrientation', this);
Service.registerState('isDefaultPortrait', this);
Service.registerState('isOnRealDevice', this);
},
handleEvent: function om_handleEvent(evt) {
switch (evt.type) {
case 'attentionclosed':
case 'sleepmenuhide':
case 'trusteduiclose':
case 'lockscreen-appclosing':
case 'searchclosing':
// We don't need to reset orientation if lockscreen is locked.
if (Service.query('locked')) {
return;
}
/**
* Fired when the orientation needs to be locked/unlocked again.
* @event module:OrientationManager#reset-orientation
*/
this.publish('reset-orientation');
break;
case 'shrinking-stop':
this.publish('reset-orientation');
break;
}
},
globalOrientation: null,
/**
* Default orientation of this device, possible values are:
*
* * portrait-primary
* * landscape-primary
*
* @type {String}
* @memberOf module:OrientationManager
*/
defaultOrientation: screen.mozOrientation,
/**
* Test if our default orientation is portrait.
* @return {Boolean} If our default orientation is portrait.
* @memberOf module:OrientationManager
*/
isDefaultPortrait: function() {
return (this.defaultOrientation === 'portrait-primary');
},
/**
* Record if we are on real device or not.
* @access private
* @type {Boolean}
* @memberOf module:OrientationManager
*/
_isOnRealDevice: undefined,
/**
* Test if we are on real device by checking the available width.
* @return {Boolean} If we are on real device or not.
* @memberOf module:OrientationManager
*/
isOnRealDevice: function sl_isOnRealDevice() {
if (typeof(this._isOnRealDevice) !== 'undefined') {
return this._isOnRealDevice;
}
// XXX: A hack to know we're using real device or not
// is to detect screen size.
// The screen size of b2g running on real device
// is the same as the size of system app.
if (window.innerWidth === screen.availWidth) {
this._isOnRealDevice = true;
} else {
this._isOnRealDevice = false;
}
return this._isOnRealDevice;
},
/**
* Get the default orientation of the device when device booted.
* This is a trick done by locking the orientation at first and
* then get by <code>screen.mozOrientation</code>.
*
* If we are not on a real device, we will guess the orientation by
* the ratio of width and height of window.
*
* @memberOf module:OrientationManager
*/
fetchDefaultOrientation: function sl_fetchDefaultOrientation() {
if (!this.isOnRealDevice()) {
// Fallback to use width/height to calculate default orientation
// if we're running on desktop browser or simulator.
this.defaultOrientation = window.innerWidth > window.innerHeight ?
'landscape-primary' : 'portrait-primary';
} else {
screen.mozLockOrientation('default');
this.defaultOrientation = screen.mozOrientation;
}
},
/**
* Get current orientation
* @return {String} Current orientation, possible values: portrait-primary,
* portrait-secondary, landscape-primary,
* landscape-secondary.
*
* @memberOf module:OrientationManager
*/
fetchCurrentOrientation: function sl_fetchCurrentOrientation() {
if (!this.isOnRealDevice()) {
// Fallback to use width/height to calculate default orientation
// if we're running on desktop browser or simulator.
return window.innerWidth > window.innerHeight ?
'landscape-primary' : 'portrait-primary';
} else {
return screen.mozOrientation;
}
},
publish: function sl_publish(eventName, detail) {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent(eventName, true, false, detail);
window.dispatchEvent(evt);
}
};
exports.OrientationManager = OrientationManager;
}(window));