diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/presentation/provider/ControllerStateMachine.jsm | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/presentation/provider/ControllerStateMachine.jsm')
-rw-r--r-- | dom/presentation/provider/ControllerStateMachine.jsm | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/dom/presentation/provider/ControllerStateMachine.jsm b/dom/presentation/provider/ControllerStateMachine.jsm new file mode 100644 index 000000000..b568a8e9a --- /dev/null +++ b/dom/presentation/provider/ControllerStateMachine.jsm @@ -0,0 +1,240 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ +/* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ +/* globals Components, dump */ + +"use strict"; + +this.EXPORTED_SYMBOLS = ["ControllerStateMachine"]; // jshint ignore:line + +const { utils: Cu } = Components; + +/* globals State, CommandType */ +Cu.import("resource://gre/modules/presentation/StateMachineHelper.jsm"); + +const DEBUG = false; +function debug(str) { + dump("-*- ControllerStateMachine: " + str + "\n"); +} + +var handlers = [ + function _initHandler(stateMachine, command) { + // shouldn't receive any command at init state. + DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line + }, + function _connectingHandler(stateMachine, command) { + switch (command.type) { + case CommandType.CONNECT_ACK: + stateMachine.state = State.CONNECTED; + stateMachine._notifyDeviceConnected(); + break; + case CommandType.DISCONNECT: + stateMachine.state = State.CLOSED; + stateMachine._notifyDisconnected(command.reason); + break; + default: + debug("unexpected command: " + JSON.stringify(command)); + // ignore unexpected command. + break; + } + }, + function _connectedHandler(stateMachine, command) { + switch (command.type) { + case CommandType.DISCONNECT: + stateMachine.state = State.CLOSED; + stateMachine._notifyDisconnected(command.reason); + break; + case CommandType.LAUNCH_ACK: + stateMachine._notifyLaunch(command.presentationId); + break; + case CommandType.TERMINATE: + stateMachine._notifyTerminate(command.presentationId); + break; + case CommandType.TERMINATE_ACK: + stateMachine._notifyTerminate(command.presentationId); + break; + case CommandType.ANSWER: + case CommandType.ICE_CANDIDATE: + stateMachine._notifyChannelDescriptor(command); + break; + case CommandType.RECONNECT_ACK: + stateMachine._notifyReconnect(command.presentationId); + break; + default: + debug("unexpected command: " + JSON.stringify(command)); + // ignore unexpected command. + break; + } + }, + function _closingHandler(stateMachine, command) { + switch (command.type) { + case CommandType.DISCONNECT: + stateMachine.state = State.CLOSED; + stateMachine._notifyDisconnected(command.reason); + break; + default: + debug("unexpected command: " + JSON.stringify(command)); + // ignore unexpected command. + break; + } + }, + function _closedHandler(stateMachine, command) { + // ignore every command in closed state. + DEBUG && debug("unexpected command: " + JSON.stringify(command)); // jshint ignore:line + }, +]; + +function ControllerStateMachine(channel, deviceId) { + this.state = State.INIT; + this._channel = channel; + this._deviceId = deviceId; +} + +ControllerStateMachine.prototype = { + launch: function _launch(presentationId, url) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.LAUNCH, + presentationId: presentationId, + url: url, + }); + } + }, + + terminate: function _terminate(presentationId) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.TERMINATE, + presentationId: presentationId, + }); + } + }, + + terminateAck: function _terminateAck(presentationId) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.TERMINATE_ACK, + presentationId: presentationId, + }); + } + }, + + reconnect: function _reconnect(presentationId, url) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.RECONNECT, + presentationId: presentationId, + url: url, + }); + } + }, + + sendOffer: function _sendOffer(offer) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.OFFER, + offer: offer, + }); + } + }, + + sendAnswer: function _sendAnswer() { + // answer can only be sent by presenting UA. + debug("controller shouldn't generate answer"); + }, + + updateIceCandidate: function _updateIceCandidate(candidate) { + if (this.state === State.CONNECTED) { + this._sendCommand({ + type: CommandType.ICE_CANDIDATE, + candidate: candidate, + }); + } + }, + + onCommand: function _onCommand(command) { + handlers[this.state](this, command); + }, + + onChannelReady: function _onChannelReady() { + if (this.state === State.INIT) { + this._sendCommand({ + type: CommandType.CONNECT, + deviceId: this._deviceId + }); + this.state = State.CONNECTING; + } + }, + + onChannelClosed: function _onChannelClose(reason, isByRemote) { + switch (this.state) { + case State.CONNECTED: + if (isByRemote) { + this.state = State.CLOSED; + this._notifyDisconnected(reason); + } else { + this._sendCommand({ + type: CommandType.DISCONNECT, + reason: reason + }); + this.state = State.CLOSING; + this._closeReason = reason; + } + break; + case State.CLOSING: + if (isByRemote) { + this.state = State.CLOSED; + if (this._closeReason) { + reason = this._closeReason; + delete this._closeReason; + } + this._notifyDisconnected(reason); + } + break; + default: + DEBUG && debug("unexpected channel close: " + reason + ", " + isByRemote); // jshint ignore:line + break; + } + }, + + _sendCommand: function _sendCommand(command) { + this._channel.sendCommand(command); + }, + + _notifyDeviceConnected: function _notifyDeviceConnected() { + //XXX trigger following command + this._channel.notifyDeviceConnected(); + }, + + _notifyDisconnected: function _notifyDisconnected(reason) { + this._channel.notifyDisconnected(reason); + }, + + _notifyLaunch: function _notifyLaunch(presentationId) { + this._channel.notifyLaunch(presentationId); + }, + + _notifyTerminate: function _notifyTerminate(presentationId) { + this._channel.notifyTerminate(presentationId); + }, + + _notifyReconnect: function _notifyReconnect(presentationId) { + this._channel.notifyReconnect(presentationId); + }, + + _notifyChannelDescriptor: function _notifyChannelDescriptor(command) { + switch (command.type) { + case CommandType.ANSWER: + this._channel.notifyAnswer(command.answer); + break; + case CommandType.ICE_CANDIDATE: + this._channel.notifyIceCandidate(command.candidate); + break; + } + }, +}; + +this.ControllerStateMachine = ControllerStateMachine; // jshint ignore:line |