'use strict';
/* global Service, DevToolsAuthDialog */
(function(exports) {
/**
* DevToolsAuth displays a prompt asking the user to scan a QR code as part of
* pairing the device with a machine running Firefox desktop. This takes
* place when debugging via WiFi to exchange keys.
* @requires DevToolsAuthDialog
* @requires ScreenManager
* @class DevToolsAuth
*/
function DevToolsAuth() {
window.addEventListener('mozChromeEvent', this);
}
DevToolsAuth.prototype = {
/**
* General event handler interface.
* Displays the pair dialog when needed.
* @memberof DevToolsAuth.prototype
* @param {DOMEvent} evt The event.
*/
handleEvent: function(e) {
if (e.detail.type !== 'devtools-auth') {
return;
}
if (e.detail.action === 'start') {
this.start();
}
if (e.detail.action === 'capture') {
this.capture();
}
if (e.detail.action === 'stop') {
this.stop();
}
},
get dialog() {
if (!this._dialog) {
this._dialog = new DevToolsAuthDialog({
onHide: this.onHide.bind(this)
});
}
return this._dialog;
},
get canvas() {
if (!this._canvas) {
this._canvas = document.createElement('canvas');
}
return this._canvas;
},
/**
* Begin capturing images that DevTools will attempt to find a QR code in
* for authentication.
* @memberof DevToolsAuth.prototype
*/
start: function() {
// We want the user's attention, so we need to turn the screen on if it's
// off.
Service.request('turnScreenOn');
this.dialog.show();
var getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia;
getUserMedia = getUserMedia.bind(navigator);
getUserMedia({
video: {
width: { min: 480 },
height: { min: 480 }
},
audio: false
}, function(stream) {
var video = this.dialog.video;
video.addEventListener('loadedmetadata', function onMetadata() {
video.removeEventListener('loadedmetadata', onMetadata);
this._resizeCanvas();
this.capture();
}.bind(this));
video.mozSrcObject = stream;
video.play();
}.bind(this), function(e) {
console.error('Unable to access camera: ' + e);
});
},
/**
* Capture another image and send to DevTools.
* @memberof DevToolsAuth.prototype
*/
capture: function() {
var video = this.dialog.video;
var canvas = this.canvas;
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var url = canvas.toDataURL('image/jpeg');
this._checkImage(url);
},
/**
* An image was successfully decoded, so further capture can stop.
* @memberof DevToolsAuth.prototype
*/
stop: function() {
this.dialog.hide('complete');
},
/**
* Dialog is now hidden, perform cleanup.
* @memberof DevToolsAuth.prototype
*/
onHide: function(reason) {
var video = this.dialog.video;
video.pause();
if (video.mozSrcObject) {
video.mozSrcObject.stop();
video.mozSrcObject = null;
}
this._canvas = null;
if (reason !== 'complete') {
this.abort();
}
},
/**
* User chose to abort the auth process.
* @memberof DevToolsAuth.prototype
*/
abort: function() {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('mozContentEvent', true, true,
{ type: 'devtools-auth',
action: 'abort' });
window.dispatchEvent(event);
},
_resizeCanvas: function() {
var video = this.dialog.video;
this.canvas.width = video.videoWidth;
this.canvas.height = video.videoHeight;
},
/**
* Dispatches an event to check a possible pairing candidate image.
* @memberof DevToolsAuth.prototype
* @param {String} url Object URL of the image to check
*/
_checkImage: function(url) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('mozContentEvent', true, true,
{ type: 'devtools-auth',
action: 'capture',
url: url });
window.dispatchEvent(event);
}
};
exports.DevToolsAuth = DevToolsAuth;
}(window));