Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
810
gaia/apps/system/js/hardware_buttons.js
Executable file
810
gaia/apps/system/js/hardware_buttons.js
Executable file
|
|
@ -0,0 +1,810 @@
|
|||
'use strict';
|
||||
|
||||
/* global Service, SettingsListener, BrowserKeyEventManager, LazyLoader */
|
||||
|
||||
(function(exports) {
|
||||
|
||||
// Tell JSHint the following script are allow to use these variables.
|
||||
// The actual functions will be defined too.
|
||||
var HardwareButtonsBaseState;
|
||||
var HardwareButtonsHomeState;
|
||||
var HardwareButtonsCameraState;
|
||||
var HardwareButtonsSleepState;
|
||||
var HardwareButtonsVolumeState;
|
||||
var HardwareButtonsWakeState;
|
||||
var HardwareButtonsScreenshotState;
|
||||
var HardwareButtonsSystemLogState;
|
||||
|
||||
/**
|
||||
* After bug 989198 landing, we will be able to listen to KeyboardEvent
|
||||
* (e.g. keydown and keyup). Also there will be new events called
|
||||
* BeforeAfterKeybaordEvent for mozbrowser-embedder iframe, say system app,
|
||||
* to control or override the bahavior of keydown/keyup event in
|
||||
* mozbrowser-embedded iframes (other apps or homescreen app).
|
||||
* These events are:
|
||||
*
|
||||
* * mozbrowserbeforekeydown
|
||||
* * mozbrowserafterkeydown
|
||||
* * mozbrowserbeforekeyup
|
||||
* * mozbrowserafterkeyup
|
||||
*
|
||||
* When a key is pressed down, the event sequence would be:
|
||||
* 1. `mozbrowserbeforekeydown` is dispatched to mozbrowser-embedder iframe
|
||||
* 2. `keydown` is dispatched to mozbrowser-embedded iframe
|
||||
* 3. `mozbrowserkeydown` is dispatched to mozbrowser-embedder iframe
|
||||
*
|
||||
* For detail, please see
|
||||
* https://wiki.mozilla.org/WebAPI/BrowserAPI/KeyboardEvent
|
||||
*
|
||||
* This module listens for KeyboardEvent and BeforeAfterKeybaordEvent,
|
||||
* processes them (with the help of BrowserKeyEventManager submodule)
|
||||
* and generates higher-level events to handle autorepeat on
|
||||
* the volume keys, long presses on Home and Sleep, and the Volume Down+Sleep
|
||||
* key combination.
|
||||
*
|
||||
* Other system app modules should listen for the high-level button events
|
||||
* generated by this module.
|
||||
*
|
||||
* The high-level events generated by this module are simple Event objects
|
||||
* that are not cancelable and do not bubble. They are dispatched at the
|
||||
* window object. The type property is set to one of these:
|
||||
*
|
||||
* | Event Type | Meaning |
|
||||
* |--------------|----------------------------------------------------------|
|
||||
* | home | short press and release of home button |
|
||||
* | holdhome | long press and hold of home button |
|
||||
* | sleep | short press and release of sleep button |
|
||||
* | wake | sleep or home pressed while sleeping |
|
||||
* | holdsleep | long press and hold of sleep button |
|
||||
* | volumeup | volume up pressed and released or autorepeated |
|
||||
* | volumedown | volume down pressed and released or autorepeated |
|
||||
* | volumedown | volume down and sleep pressed at same time (used for |
|
||||
* | + sleep | screenshots) |
|
||||
* | volumedown | volume up and sleep pressed at same time (used for |
|
||||
* | + volumeup | systemlog capture) |
|
||||
* | camera | short press and release of camera button |
|
||||
* | holdcamera | long press and hold of camera button |
|
||||
*
|
||||
* Because these events are fired at the window object, they cannot be
|
||||
* captured. Many modules listen for the home event. Those that want
|
||||
* to respond to it and prevent others from responding should call
|
||||
* `stopImmediatePropagation()`. Overlays that want to prevent the window
|
||||
* manager from showing the homescreen on the home event should call that
|
||||
* method. Note, however, that this only works for scripts that run and
|
||||
* register their event handlers before `AppWindowManager` does.
|
||||
*
|
||||
* As of the implementation itself, we process events with a
|
||||
* finite state machine.
|
||||
* Each state object has a `process()` method for handling events.
|
||||
* And optionally has `enter()` and `exit()` methods called when the FSM
|
||||
* enters and exits that state.
|
||||
*
|
||||
* @example
|
||||
* var hardwareButtons = new HardwareButtons();
|
||||
* hardwareButtons.start(); // Attach the event listeners.
|
||||
* hardwareButtons.stop(); // Deattach the event listeners.
|
||||
*
|
||||
* @class HardwareButtons
|
||||
* @requires Service
|
||||
* @requires BrowserKeyEventManager
|
||||
**/
|
||||
var HardwareButtons = function HardwareButtons() {
|
||||
this._started = false;
|
||||
this._softwareHome = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* A mapping between state keyboard and the constructor.
|
||||
* @type {Object}
|
||||
*/
|
||||
HardwareButtons.STATES = {};
|
||||
|
||||
/**
|
||||
* How long for press and hold Home or Sleep.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @type {Number}
|
||||
*/
|
||||
HardwareButtons.prototype.HOLD_INTERVAL = 750;
|
||||
|
||||
/**
|
||||
* How long before volume autorepeat begins.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @type {Number}
|
||||
*/
|
||||
HardwareButtons.prototype.REPEAT_DELAY = 700;
|
||||
|
||||
/**
|
||||
* How fast the autorepeat is.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @type {Number}
|
||||
*/
|
||||
HardwareButtons.prototype.REPEAT_INTERVAL = 100;
|
||||
|
||||
/**
|
||||
* Start listening to events from Gecko and FSM.
|
||||
* @memberof HardwareButtons.prototype
|
||||
*/
|
||||
HardwareButtons.prototype.start = function hb_start() {
|
||||
if (this._started) {
|
||||
throw 'Instance should not be start()\'ed twice.';
|
||||
}
|
||||
this._started = true;
|
||||
|
||||
// Kick off the FSM in the base state
|
||||
this.state = new HardwareButtonsBaseState(this);
|
||||
|
||||
window.addEventListener('softwareButtonEvent', this);
|
||||
|
||||
// These event handler listens for hardware button events and passes the
|
||||
// event type to the process() method of the current state for processing
|
||||
window.addEventListener('mozbrowserbeforekeydown', this);
|
||||
window.addEventListener('mozbrowserbeforekeyup', this);
|
||||
window.addEventListener('mozbrowserafterkeydown', this);
|
||||
window.addEventListener('mozbrowserafterkeyup', this);
|
||||
window.addEventListener('keydown', this);
|
||||
window.addEventListener('keyup', this);
|
||||
|
||||
SettingsListener.observe('software-button.enabled', false, function(value) {
|
||||
this._softwareHome = value;
|
||||
}.bind(this));
|
||||
|
||||
|
||||
return LazyLoader.load(['js/browser_key_event_manager.js']).then(() => {
|
||||
// initiate BrowserKeyEventManager submodule
|
||||
this.browserKeyEventManager = new BrowserKeyEventManager();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop listening to events. Must call before throwing away the instance
|
||||
* to avoid memory leaks.
|
||||
* @memberof HardwareButtons.prototype
|
||||
*/
|
||||
HardwareButtons.prototype.stop = function hb_stop() {
|
||||
if (!this._started) {
|
||||
throw 'Instance was never start()\'ed but stop() is called.';
|
||||
}
|
||||
this._started = false;
|
||||
|
||||
// Exit the current state()
|
||||
if (this.state && this.state.exit) {
|
||||
this.state.exit();
|
||||
}
|
||||
|
||||
this.state = null;
|
||||
|
||||
window.removeEventListener('softwareButtonEvent', this);
|
||||
|
||||
window.removeEventListener('mozbrowserbeforekeydown', this);
|
||||
window.removeEventListener('mozbrowserbeforekeyup', this);
|
||||
window.removeEventListener('mozbrowserafterkeydown', this);
|
||||
window.removeEventListener('mozbrowserafterkeyup', this);
|
||||
window.removeEventListener('keydown', this);
|
||||
window.removeEventListener('keyup', this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch a high-level event of the specified type.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @param {String} type name of the event.
|
||||
*/
|
||||
HardwareButtons.prototype.publish = function hb_publish(type) {
|
||||
window.dispatchEvent(new CustomEvent(type, { bubbles: type === 'home' }));
|
||||
};
|
||||
|
||||
/**
|
||||
* Transit the FSM to a new state.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @param {String} s Keyword of the new state to switch to.
|
||||
* @param {String} type Name of the event to handle
|
||||
*/
|
||||
HardwareButtons.prototype.setState = function hb_setState(s, type) {
|
||||
// Exit the current state()
|
||||
if (this.state && this.state.exit) {
|
||||
this.state.exit(type);
|
||||
}
|
||||
|
||||
this.state = new HardwareButtons.STATES[s](this);
|
||||
|
||||
// Enter the new this.state
|
||||
if (this.state && this.state.enter) {
|
||||
this.state.enter(type);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle events from Gecko.
|
||||
* @memberof HardwareButtons.prototype
|
||||
* @param {Object} evt Event.
|
||||
*/
|
||||
HardwareButtons.prototype.handleEvent = function hb_handleEvent(evt) {
|
||||
// When the software home button is displayed we ignore the hardware
|
||||
// home button if there is one
|
||||
var hardwareHomeEvent =
|
||||
(this.browserKeyEventManager.isHardwareKeyEvent(evt.type)) &&
|
||||
this.browserKeyEventManager.isHomeKey(evt);
|
||||
if (this._softwareHome && hardwareHomeEvent) {
|
||||
// Given that software home button is enabled, when we receive
|
||||
// mozbrowserbeforekeydown/mozbrowserbeforekeyup event of home button in
|
||||
// system app, Gecko will dispatch keydown/keyup events to embedded frame
|
||||
// (i.e. Homescreen app or web pages in browser). Even though these apps
|
||||
// or web pages do not listen to 'Home' key events, there are still
|
||||
// default action. The default action usually is to scroll to top of the
|
||||
// page. That's why we need to call preventDefault() here.
|
||||
// See https://bugzil.la/1105285#c12 for detail.
|
||||
evt.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.type === 'softwareButtonEvent') {
|
||||
var type = evt.detail.type;
|
||||
switch (type) {
|
||||
case 'home-button-press':
|
||||
case 'home-button-release':
|
||||
case 'sleep-button-press':
|
||||
case 'sleep-button-release':
|
||||
case 'volume-up-button-press':
|
||||
case 'volume-up-button-release':
|
||||
case 'volume-down-button-press':
|
||||
case 'volume-down-button-release':
|
||||
this.state.process(type);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Figure out if we should process this key event here in the
|
||||
// system app. The browserKeyEventManager returns an event name
|
||||
// (like 'volume-down-button-press') if we should process it and
|
||||
// returns undefined otherwise. Note that the value returned
|
||||
// may depend on whether or not there is already a button pressed.
|
||||
var isButtonPressed = !(this.state instanceof HardwareButtonsBaseState);
|
||||
var buttonEventType =
|
||||
this.browserKeyEventManager.getButtonEventType(evt, isButtonPressed);
|
||||
if (buttonEventType) {
|
||||
this.state.process(buttonEventType);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The base state is the default, when no hardware buttons are pressed.
|
||||
*
|
||||
* @class HardwareButtonsBaseState
|
||||
*/
|
||||
HardwareButtonsBaseState =
|
||||
HardwareButtons.STATES.base = function HardwareButtonsBaseState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsBaseState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsBaseState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'home-button-press':
|
||||
/**
|
||||
* If the phone is sleeping, then pressing Home wakes it
|
||||
* (on press, not release)
|
||||
* @event HardwareButtonsBaseState#wake
|
||||
*/
|
||||
// XXX: Unresolved dependency to screenManager
|
||||
if (!Service.query('screenEnabled')) {
|
||||
this.hardwareButtons.publish('wake');
|
||||
this.hardwareButtons.setState('wake', type);
|
||||
} else {
|
||||
this.hardwareButtons.setState('home', type);
|
||||
}
|
||||
return;
|
||||
case 'sleep-button-press':
|
||||
/**
|
||||
* If the phone is sleeping, then pressing Home wakes it
|
||||
* (on press, not release)
|
||||
* @event HardwareButtonsBaseState#wake
|
||||
*/
|
||||
// XXX: Unresolved dependency to screenManager
|
||||
if (!Service.query('screenEnabled')) {
|
||||
this.hardwareButtons.publish('wake');
|
||||
this.hardwareButtons.setState('wake', type);
|
||||
} else {
|
||||
this.hardwareButtons.setState('sleep', type);
|
||||
}
|
||||
return;
|
||||
case 'volume-up-button-press':
|
||||
case 'volume-down-button-press':
|
||||
this.hardwareButtons.setState('volume', type);
|
||||
return;
|
||||
case 'camera-button-press':
|
||||
this.hardwareButtons.setState('camera', type);
|
||||
return;
|
||||
case 'home-button-release':
|
||||
case 'sleep-button-release':
|
||||
case 'volume-up-button-release':
|
||||
case 'volume-down-button-release':
|
||||
case 'camera-button-release':
|
||||
// Ignore button releases that occur in this state.
|
||||
// These can happen after volumedown+sleep and home+volume.
|
||||
return;
|
||||
}
|
||||
console.error('Unexpected hardware key: ', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the home state when the user presses the Home button
|
||||
* We can fire home or holdhome events from this state
|
||||
*
|
||||
* @class HardwareButtonsHomeState
|
||||
*/
|
||||
HardwareButtonsHomeState =
|
||||
HardwareButtons.STATES.home = function HardwareButtonsHomeState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsHomeState.prototype
|
||||
*/
|
||||
HardwareButtonsHomeState.prototype.enter = function() {
|
||||
this.timer = setTimeout(function() {
|
||||
/**
|
||||
* When the user holds Home button more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsHomeState#holdhome
|
||||
*/
|
||||
this.hardwareButtons.publish('holdhome');
|
||||
navigator.vibrate(50);
|
||||
this.hardwareButtons.setState('base');
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsHomeState.prototype
|
||||
*/
|
||||
HardwareButtonsHomeState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsHomeState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsHomeState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'home-button-release':
|
||||
/**
|
||||
* When the user releases Home button before HOLD_INTERVAL.
|
||||
* @event HardwareButtonsHomeState#home
|
||||
*/
|
||||
this.hardwareButtons.publish('home');
|
||||
navigator.vibrate(50);
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
case 'volume-up-button-press':
|
||||
case 'volume-down-button-press':
|
||||
case 'sleep-button-press':
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
}
|
||||
console.error('Unexpected hardware key: ', type);
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the sleep state when the user presses the Sleep button
|
||||
* We can fire sleep, or holdsleep events from this state.
|
||||
*
|
||||
* @class HardwareButtonsSleepState
|
||||
*/
|
||||
HardwareButtonsSleepState =
|
||||
HardwareButtons.STATES.sleep = function HardwareButtonsSleepState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsSleepState.prototype
|
||||
*/
|
||||
HardwareButtonsSleepState.prototype.enter = function() {
|
||||
this.timer = setTimeout(function() {
|
||||
/**
|
||||
* When the user holds Sleep button more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsSleepState#holdsleep
|
||||
*/
|
||||
this.hardwareButtons.publish('holdsleep');
|
||||
this.hardwareButtons.setState('base');
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsSleepState.prototype
|
||||
*/
|
||||
HardwareButtonsSleepState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsSleepState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsSleepState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'sleep-button-release':
|
||||
/**
|
||||
* When the user releases Sleep button before HOLD_INTERVAL.
|
||||
* @event HardwareButtonsSleepState#sleep
|
||||
*/
|
||||
this.hardwareButtons.publish('sleep');
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
case 'volume-down-button-press':
|
||||
/**
|
||||
* When the user presses Volume Down button, before HOLD_INTERVAL,
|
||||
* while holding the Sleep button.
|
||||
*/
|
||||
this.hardwareButtons.setState('screenshot', type);
|
||||
return;
|
||||
case 'home-button-press':
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
}
|
||||
console.error('Unexpected hardware key: ', type);
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the volume state when the user presses the volume up or
|
||||
* volume down buttons.
|
||||
* We can fire volumeup and volumedown events from this state
|
||||
*
|
||||
* @class HardwareButtonsVolumeState
|
||||
*
|
||||
*/
|
||||
HardwareButtonsVolumeState =
|
||||
HardwareButtons.STATES.volume = function HardwareButtonsVolumeState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
this.repeating = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger repeat actions for volume buttons.
|
||||
* @memberof HardwareButtonsVolumeState.prototype
|
||||
*/
|
||||
HardwareButtonsVolumeState.prototype.repeat = function() {
|
||||
this.repeating = true;
|
||||
if (this.direction === 'volume-up-button-press') {
|
||||
/**
|
||||
* Volume up pressed and released or autorepeated.
|
||||
* @event HardwareButtonsVolumeState#volumeup
|
||||
*/
|
||||
this.hardwareButtons.publish('volumeup');
|
||||
} else {
|
||||
/**
|
||||
* Volume down pressed and released or autorepeated.
|
||||
* @event HardwareButtonsVolumeState#volumedown
|
||||
*/
|
||||
this.hardwareButtons.publish('volumedown');
|
||||
}
|
||||
this.timer = setTimeout(this.repeat.bind(this),
|
||||
this.hardwareButtons.REPEAT_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsVolumeState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsVolumeState.prototype.enter = function(type) {
|
||||
this.direction = type; // Is volume going up or down?
|
||||
this.repeating = false;
|
||||
this.timer =
|
||||
setTimeout(this.repeat.bind(this), this.hardwareButtons.REPEAT_DELAY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsVolumeState.prototype
|
||||
*/
|
||||
HardwareButtonsVolumeState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsVolumeState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsVolumeState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'home-button-press':
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
case 'sleep-button-press':
|
||||
if (this.direction === 'volume-down-button-press') {
|
||||
/**
|
||||
* When the user presses Sleep button, before HOLD_INTERVAL,
|
||||
* while holding the Volume Down button.
|
||||
*/
|
||||
this.hardwareButtons.setState('screenshot', type);
|
||||
return;
|
||||
}
|
||||
this.hardwareButtons.setState('sleep', type);
|
||||
return;
|
||||
case 'volume-down-button-press':
|
||||
case 'volume-up-button-press':
|
||||
this.hardwareButtons.setState('systemlog', type);
|
||||
return;
|
||||
case 'volume-up-button-release':
|
||||
if (this.direction === 'volume-up-button-press') {
|
||||
if (!this.repeating) {
|
||||
this.hardwareButtons.publish('volumeup');
|
||||
}
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'volume-down-button-release':
|
||||
if (this.direction === 'volume-down-button-press') {
|
||||
if (!this.repeating) {
|
||||
this.hardwareButtons.publish('volumedown');
|
||||
}
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Ignore anything else (such as sleep button release)
|
||||
return;
|
||||
}
|
||||
console.error('Unexpected hardware key: ', type);
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter this state when the user presses Home or Sleep on a sleeping
|
||||
* phone. We give immediate feedback by waking the phone up on the press
|
||||
* rather than waiting for the release, but this means we need a special
|
||||
* state so that we don't actually send a home or sleep event on the
|
||||
* key release. Note, however, that this state does set a timer so that
|
||||
* it can send holdhome or holdsleep events. (This means that pressing and
|
||||
* holding sleep will bring up the power menu, even on a sleeping phone.)
|
||||
*
|
||||
* @class HardwareButtonsWakeState
|
||||
*/
|
||||
HardwareButtonsWakeState =
|
||||
HardwareButtons.STATES.wake = function HardwareButtonsWakeState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
this.delegateState = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsWakeState.prototype
|
||||
*/
|
||||
HardwareButtonsWakeState.prototype.enter = function(type) {
|
||||
if (type === 'home-button-press') {
|
||||
this.delegateState = new HardwareButtonsHomeState(this.hardwareButtons);
|
||||
} else {
|
||||
this.delegateState = new HardwareButtonsSleepState(this.hardwareButtons);
|
||||
}
|
||||
|
||||
this.timer = setTimeout(function() {
|
||||
if (type === 'home-button-press') {
|
||||
/**
|
||||
* When the user holds Home button more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsWakeState#holdhome
|
||||
*/
|
||||
this.hardwareButtons.publish('holdhome');
|
||||
} else if (type === 'sleep-button-press') {
|
||||
/**
|
||||
* When the user holds Sleep button more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsWakeState#holdsleep
|
||||
*/
|
||||
this.hardwareButtons.publish('holdsleep');
|
||||
}
|
||||
this.hardwareButtons.setState('base', type);
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsWakeState.prototype
|
||||
*/
|
||||
HardwareButtonsWakeState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsWakeState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsWakeState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'home-button-release':
|
||||
case 'sleep-button-release':
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
default:
|
||||
this.delegateState.process(type);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the screenshot home state when the user presses the Power button
|
||||
* and Volume Down button within less than HOLD_INTERVAL of each other
|
||||
* We can fire home or holdhome events from this state
|
||||
*
|
||||
* @class HardwareButtonsScreenshotState
|
||||
*/
|
||||
HardwareButtonsScreenshotState =
|
||||
HardwareButtons.STATES.screenshot =
|
||||
function HardwareButtonsScreenshotState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsScreenshotState.prototype
|
||||
*/
|
||||
HardwareButtonsScreenshotState.prototype.enter = function() {
|
||||
this.timer = setTimeout(function() {
|
||||
/**
|
||||
* When the user holds Volume Down and Power button
|
||||
* more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsHomeState#volumedown+sleep
|
||||
*/
|
||||
this.hardwareButtons.publish('volumedown+sleep');
|
||||
this.hardwareButtons.setState('base');
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsScreenshotState.prototype
|
||||
*/
|
||||
HardwareButtonsScreenshotState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pressing any other hardware button will cancel this state.
|
||||
* @memberof HardwareButtonsScreenshotState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsScreenshotState.prototype.process = function(type) {
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the systemlog home state when the user presses the Power button
|
||||
* and Volume Down button within less than HOLD_INTERVAL of each other
|
||||
* We can fire home or holdhome events from this state
|
||||
*
|
||||
* @class HardwareButtonsSystemLogState
|
||||
*/
|
||||
HardwareButtonsSystemLogState =
|
||||
HardwareButtons.STATES.systemlog =
|
||||
function HardwareButtonsSystemLogState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsSystemLogState.prototype
|
||||
*/
|
||||
HardwareButtonsSystemLogState.prototype.enter = function() {
|
||||
this.timer = setTimeout(function() {
|
||||
/**
|
||||
* When the user holds Volume Up and Volume Down button
|
||||
* more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsHomeState#volumeup+volumedown
|
||||
*/
|
||||
this.hardwareButtons.publish('volumeup+volumedown');
|
||||
this.hardwareButtons.setState('base');
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsSystemLogState.prototype
|
||||
*/
|
||||
HardwareButtonsSystemLogState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pressing any other hardware button will cancel this state.
|
||||
* @memberof HardwareButtonsSystemLogState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsSystemLogState.prototype.process = function(type) {
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
/**
|
||||
* We enter the camera state when the user presses the Camera button
|
||||
* We can fire camera or holdcamera events from this state
|
||||
*
|
||||
* @class HardwareButtonsCameraState
|
||||
*/
|
||||
HardwareButtonsCameraState =
|
||||
HardwareButtons.STATES.camera = function HardwareButtonsCameraState(hb) {
|
||||
this.hardwareButtons = hb;
|
||||
this.timer = undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entering the state.
|
||||
* @memberof HardwareButtonsCameraState.prototype
|
||||
*/
|
||||
HardwareButtonsCameraState.prototype.enter = function() {
|
||||
this.timer = setTimeout(function() {
|
||||
/**
|
||||
* When the user holds Camera button more than HOLD_INTERVAL.
|
||||
* @event HardwareButtonsCameraState#holdcamera
|
||||
*/
|
||||
this.hardwareButtons.publish('holdcamera');
|
||||
navigator.vibrate(50);
|
||||
this.hardwareButtons.setState('base');
|
||||
}.bind(this), this.hardwareButtons.HOLD_INTERVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Leaving the state.
|
||||
* @memberof HardwareButtonsCameraState.prototype
|
||||
*/
|
||||
HardwareButtonsCameraState.prototype.exit = function() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the event, maybe transition the state.
|
||||
* @memberof HardwareButtonsCameraState.prototype
|
||||
* @param {String} type Name of the event to process.
|
||||
*/
|
||||
HardwareButtonsCameraState.prototype.process = function(type) {
|
||||
switch (type) {
|
||||
case 'camera-button-release':
|
||||
/**
|
||||
* When the user releases Camera button before HOLD_INTERVAL.
|
||||
* @event HardwareButtonsCameraState#camera
|
||||
*/
|
||||
this.hardwareButtons.setState('base', type);
|
||||
return;
|
||||
}
|
||||
this.hardwareButtons.setState('base', type);
|
||||
};
|
||||
|
||||
exports.HardwareButtons = HardwareButtons;
|
||||
}(window));
|
||||
Loading…
Reference in a new issue