-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for auto install of Firefox screen sharing extension #238
base: develop
Are you sure you want to change the base?
Changes from all commits
04ff8df
9289ad5
89bc156
e6cb708
13256de
7fd246c
5a537a2
49b45f6
de5bac2
134ccaa
2e3155f
e8c2841
160d3bb
481c745
29d3fdd
8a4205b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Spreed WebRTC. | ||
* Copyright (C) 2013-2015 struktur AG | ||
* | ||
* This file is part of Spreed WebRTC. | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
"use strict"; | ||
define(["underscore", "jquery", "webrtc.adapter"], function(_, $) { | ||
|
||
// firefoxExtension | ||
return ["$window", "$q", "alertify", "translation", "$interval", function($window, $q, alertify, translation, $interval) { | ||
|
||
var EXTENSION_DOM_ID = 'firefoxextension-available'; | ||
|
||
var intervalSecs = 50; | ||
var intervalCount = 1; | ||
var isAvailable = function() { | ||
return $window.document.getElementById(EXTENSION_DOM_ID); | ||
}; | ||
|
||
var FirefoxExtension = function() { | ||
this.available = false; | ||
this.e = $({}); | ||
this.autoinstall = {}; | ||
this.initialize(); | ||
}; | ||
|
||
FirefoxExtension.prototype.initialize = function() { | ||
if (isAvailable()) { | ||
this.available = true; | ||
console.log("Firefox extension is available."); | ||
this.e.triggerHandler("available", true); | ||
} else if (this.available) { | ||
this.available = false; | ||
console.log("Firefox extension is no longer available."); | ||
this.e.triggerHandler("available", false); | ||
} | ||
}; | ||
|
||
FirefoxExtension.prototype.registerAutoInstall = function(installFunc, cancelInstallFunc, force) { | ||
this.autoinstall.install = installFunc; | ||
this.autoinstall.cancel = cancelInstallFunc; | ||
this.autoinstall.force = !!force; | ||
if (!this.available && installFunc) { | ||
this.e.triggerHandler("available", true); | ||
} | ||
}; | ||
|
||
/** | ||
* Checks for availability of the Firefox extension by looking for the id which the extension | ||
* will append to the body of the document. Unfortunately there is no callback | ||
* API implemented by Firefox which will allow other domains to see if an | ||
* extension is installed using `InstallTrigger.install`. Only priviledged | ||
* domains may use the callback. | ||
* | ||
* @param {int} How long of a timespan the function should check for the extension install at intervalSecs interval rate | ||
* @return {promise} | ||
*/ | ||
FirefoxExtension.prototype.detectInstalled = function(maxTimeout) { | ||
var defer = $q.defer(); | ||
var that = this; | ||
|
||
var intervalPromise = $interval(function() { | ||
if (isAvailable()) { | ||
console.log("Auto install success Firefox extension"); | ||
$interval.cancel(intervalPromise); | ||
that.initialize(); | ||
defer.resolve("Auto install success Firefox extension"); | ||
} else if (intervalCount * intervalSecs >= maxTimeout) { | ||
$interval.cancel(intervalPromise); | ||
defer.reject("Timeout while waiting for extension to become available"); | ||
} | ||
intervalCount++; | ||
}, intervalSecs); | ||
|
||
return defer.promise; | ||
}; | ||
|
||
// Create extension api and wait for messages. | ||
var extension = new FirefoxExtension(); | ||
|
||
// Expose. | ||
return extension; | ||
|
||
}]; | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,8 +32,11 @@ define(['underscore', 'text!partials/screensharedialogff.html', 'webrtc.adapter' | |
}; | ||
}]; | ||
|
||
var GLOBAL_SCREENSHARING_START_EVENT = new Event('webrtcStartScreensharing'); | ||
var GLOBAL_SCREENSHARING_STOP_EVENT = new Event('webrtcStopScreensharing'); | ||
|
||
// screensharing | ||
return ["$window", "$q", "$timeout", "chromeExtension", "dialogs", "$templateCache", function($window, $q, $timeout, chromeExtension, dialogs, $templateCache) { | ||
return ["$window", "$q", "$timeout", "chromeExtension", "firefoxExtension", "dialogs", "$templateCache", function($window, $q, $timeout, chromeExtension, firefoxExtension, dialogs, $templateCache) { | ||
|
||
$templateCache.put('/dialogs/screensharedialogff.html', screenshareDialogFF); | ||
|
||
|
@@ -43,6 +46,18 @@ define(['underscore', 'text!partials/screensharedialogff.html', 'webrtc.adapter' | |
chromeExtension.e.on("available", _.bind(function() { | ||
this.initialize(); | ||
}, this)); | ||
firefoxExtension.e.on("available", _.bind(function() { | ||
this.initialize(); | ||
}, this)); | ||
}; | ||
|
||
Screensharing.prototype.globalNotify = { | ||
screensharingStart: function() { | ||
$window.dispatchEvent(GLOBAL_SCREENSHARING_START_EVENT); | ||
}, | ||
screensharingStop: function() { | ||
$window.dispatchEvent(GLOBAL_SCREENSHARING_STOP_EVENT); | ||
} | ||
}; | ||
|
||
Screensharing.prototype.initialize = function() { | ||
|
@@ -53,6 +68,29 @@ define(['underscore', 'text!partials/screensharedialogff.html', 'webrtc.adapter' | |
// Define our helpers. | ||
this.prepare = null; | ||
this.cancel = null; | ||
var that = this; | ||
|
||
var selectFirefoxScreenToShare = function(options) { | ||
// To work, the current domain must be whitelisted in | ||
// media.getusermedia.screensharing.allowed_domains (about:config). | ||
// See https://wiki.mozilla.org/Screensharing for reference. | ||
that.globalNotify.screensharingStart(); | ||
var d = $q.defer(); | ||
var dlg = dialogs.create('/dialogs/screensharedialogff.html', screenshareDialogFFController, {selection: "screen"}, {}); | ||
dlg.result.then(function(source) { | ||
if (source) { | ||
var opts = _.extend({ | ||
mediaSource: source | ||
}, options); | ||
d.resolve(opts); | ||
} else { | ||
d.resolve(null); | ||
} | ||
}, function(err) { | ||
d.resolve(null); | ||
}); | ||
return d.promise; | ||
}; | ||
|
||
// Chrome support. | ||
if ($window.webrtcDetectedBrowser === "chrome") { | ||
|
@@ -133,44 +171,29 @@ define(['underscore', 'text!partials/screensharedialogff.html', 'webrtc.adapter' | |
|
||
} | ||
|
||
} else if ($window.webrtcDetectedBrowser === "firefox") { | ||
} else if ($window.webrtcDetectedBrowser === "firefox" && $window.webrtcDetectedVersion >= 36) { | ||
|
||
// Firefox 36 got screen sharing support. | ||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=923225 | ||
if ($window.webrtcDetectedVersion >= 36) { | ||
this.prepare = function(options) { | ||
return selectFirefoxScreenToShare(options); | ||
}; | ||
if (firefoxExtension.available) { | ||
this.supported = true; | ||
} else if (!firefoxExtension.autoinstall.force) { | ||
this.supported = true; | ||
this.prepare = function(options) { | ||
// To work, the current domain must be whitelisted in | ||
// media.getusermedia.screensharing.allowed_domains (about:config). | ||
// See https://wiki.mozilla.org/Screensharing for reference. | ||
var d = $q.defer(); | ||
var dlg = dialogs.create('/dialogs/screensharedialogff.html', screenshareDialogFFController, {selection: "screen"}, {}); | ||
dlg.result.then(function(source) { | ||
if (source) { | ||
var opts = _.extend({ | ||
mediaSource: source | ||
}, options); | ||
d.resolve(opts); | ||
} else { | ||
d.resolve(null); | ||
} | ||
}, function(err) { | ||
d.resolve(null); | ||
}); | ||
return d.promise; | ||
}; | ||
} | ||
|
||
} else { | ||
// No support for screen sharing. | ||
} | ||
|
||
var waiting = false; | ||
var prepareAlternative = this.prepare; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is not good about this? The variables are available in this scope level anyway. Declaring them here makes it more clear when used for Firefox as well. |
||
|
||
// Auto install support. | ||
if (!this.supported && chromeExtension.autoinstall.install) { | ||
this.supported = this.autoinstall = true; | ||
var that = this; | ||
var waiting = false; | ||
var prepareAlternative = this.prepare; | ||
this.prepare = function(options) { | ||
var d = $q.defer(); | ||
var install = chromeExtension.autoinstall.install(); | ||
|
@@ -230,6 +253,46 @@ define(['underscore', 'text!partials/screensharedialogff.html', 'webrtc.adapter' | |
} | ||
waiting = false; | ||
}; | ||
} else if (!this.supported && firefoxExtension.autoinstall.install) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clean up the if else if !this.supported check. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand what you want me to cleanup here. |
||
this.supported = this.autoinstall = true; | ||
this.prepare = function(options) { | ||
var d = $q.defer(); | ||
var install = firefoxExtension.autoinstall.install(); | ||
install.then(function() { | ||
var starter = function() { | ||
var prepare = selectFirefoxScreenToShare(options); | ||
prepare.then(function(id) { | ||
d.resolve(id); | ||
}, function(err) { | ||
d.reject(err); | ||
}); | ||
}; | ||
firefoxExtension.detectInstalled(30000).then(function() { | ||
starter(); | ||
}, function(reason) { | ||
d.reject(reason); | ||
}); | ||
}, function(err) { | ||
console.log("Auto install of extension failed.", err); | ||
if (prepareAlternative) { | ||
var alternative = prepareAlternative(options); | ||
alternative.then(function(id) { | ||
d.resolve(id); | ||
}, function() { | ||
d.reject(err); | ||
}); | ||
} else { | ||
d.reject(err); | ||
} | ||
}); | ||
return d.promise; | ||
}; | ||
this.cancel = function() { | ||
if (firefoxExtension.autoinstall.cancel) { | ||
firefoxExtension.autoinstall.cancel(); | ||
} | ||
waiting = false; | ||
}; | ||
} else { | ||
this.autoinstall = false; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only define this when Firefox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that
is used throughout theinitialize
function. See lines 213 and 220. The initialize function should really be broken up.