Add options check.

This patch avoids main process never response back to renderer if the options is
invalid.
This commit is contained in:
Haojian Wu 2015-10-19 10:54:12 +08:00
parent 214f8477b3
commit fb4efec55d
4 changed files with 37 additions and 22 deletions

View file

@ -41,6 +41,24 @@ namespace api {
namespace { namespace {
const int kThumbnailWidth = 150; const int kThumbnailWidth = 150;
const int kThumbnailHeight = 150; const int kThumbnailHeight = 150;
bool GetCapturerTypes(const mate::Dictionary& args,
bool* show_windows,
bool* show_screens) {
*show_windows = false;
*show_screens = false;
std::vector<std::string> sources;
if (!args.Get("types", &sources))
return false;
for (const auto& source_type : sources) {
if (source_type == "screen")
*show_screens = true;
else if (source_type == "window")
*show_windows = true;
}
return !show_windows && !show_screens ? false : true;
}
} // namespace } // namespace
DesktopCapturer::DesktopCapturer() { DesktopCapturer::DesktopCapturer() {
@ -50,21 +68,14 @@ DesktopCapturer::~DesktopCapturer() {
} }
void DesktopCapturer::StartHandling(const mate::Dictionary& args) { void DesktopCapturer::StartHandling(const mate::Dictionary& args) {
std::vector<std::string> sources;
if (!args.Get("types", &sources))
return;
bool show_screens = false; bool show_screens = false;
bool show_windows = false; bool show_windows = false;
for (const auto& source_type : sources) { if (!GetCapturerTypes(args, &show_windows, &show_screens)) {
if (source_type == "screen") Emit("handling-finished",
show_screens = true; "Invalid options.",
else if (source_type == "window") std::vector<DesktopMediaList::Source>());
show_windows = true;
}
if (!show_windows && !show_screens)
return; return;
}
webrtc::DesktopCaptureOptions options = webrtc::DesktopCaptureOptions options =
webrtc::DesktopCaptureOptions::CreateDefault(); webrtc::DesktopCaptureOptions::CreateDefault();
@ -113,7 +124,7 @@ bool DesktopCapturer::OnRefreshFinished() {
for (int i = 0; i < media_list_->GetSourceCount(); ++i) for (int i = 0; i < media_list_->GetSourceCount(); ++i)
sources.push_back(media_list_->GetSource(i)); sources.push_back(media_list_->GetSource(i));
media_list_.reset(); media_list_.reset();
Emit("refresh-finished", sources); Emit("handling-finished", "", sources);
return false; return false;
} }

View file

@ -11,25 +11,26 @@ requestsQueue = []
ipc.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, options) -> ipc.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, options) ->
request = { options: options, webContents: event.sender } request = { options: options, webContents: event.sender }
desktopCapturer.startHandling options if requestsQueue.length is 0
requestsQueue.push request requestsQueue.push request
desktopCapturer.startHandling options if requestsQueue.length is 1
# If the WebContents is destroyed before receiving result, just remove the # If the WebContents is destroyed before receiving result, just remove the
# reference from requestsQueue to make the module not send the result to it. # reference from requestsQueue to make the module not send the result to it.
event.sender.once 'destroyed', () -> event.sender.once 'destroyed', () ->
request.webContents = null request.webContents = null
desktopCapturer.emit = (event_name, event, sources) -> desktopCapturer.emit = (event_name, event, error_message, sources) ->
# Receiving sources result from main process, now send them back to renderer. # Receiving sources result from main process, now send them back to renderer.
handledRequest = requestsQueue.shift 0 handledRequest = requestsQueue.shift 0
error = if error_message then Error error_message else null
result = ({ id: source.id, name: source.name, thumbnail: source.thumbnail.toDataUrl() } for source in sources) result = ({ id: source.id, name: source.name, thumbnail: source.thumbnail.toDataUrl() } for source in sources)
handledRequest.webContents?.send 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', result handledRequest.webContents?.send 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', error_message, result
# Check the queue to see whether there is other same request. If has, handle # Check the queue to see whether there is other same request. If has, handle
# it for reducing redunplicated `desktopCaptuer.startHandling` calls. # it for reducing redunplicated `desktopCaptuer.startHandling` calls.
unhandledRequestsQueue = [] unhandledRequestsQueue = []
for request in requestsQueue for request in requestsQueue
if isOptionsEqual handledRequest.options, request.options if isOptionsEqual handledRequest.options, request.options
request.webContents?.send 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', result request.webContents?.send 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', error_message, result
else else
unhandledRequestsQueue.push request unhandledRequestsQueue.push request
requestsQueue = unhandledRequestsQueue requestsQueue = unhandledRequestsQueue

View file

@ -3,8 +3,9 @@ NativeImage = require 'native-image'
getSources = (options, callback) -> getSources = (options, callback) ->
ipc.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', options ipc.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', options
ipc.once 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', (sources) -> ipc.once 'ATOM_RENDERER_DESKTOP_CAPTURER_RESULT', (error_message, sources) ->
callback ({id: source.id, name: source.name, thumbnail: NativeImage.createFromDataUrl source.thumbnail} for source in sources) error = if error_message then Error error_message else null
callback error, ({id: source.id, name: source.name, thumbnail: NativeImage.createFromDataUrl source.thumbnail} for source in sources)
module.exports = module.exports =
getSources: getSources getSources: getSources

View file

@ -7,7 +7,8 @@ screen and individual app windows.
// In the renderer process. // In the renderer process.
var desktopCapturer = require('desktop-capturer'); var desktopCapturer = require('desktop-capturer');
desktopCapturer.getSources({types: ['window', 'screen']}, function(sources) { desktopCapturer.getSources({types: ['window', 'screen']}, function(error, sources) {
if (error) throw error;
for (var i = 0; i < sources.length; ++i) { for (var i = 0; i < sources.length; ++i) {
if (sources[i].name == "Electron") { if (sources[i].name == "Electron") {
navigator.webkitGetUserMedia({ navigator.webkitGetUserMedia({
@ -52,9 +53,10 @@ The `desktopCapturer` module has the following methods:
* `width` Integer - The width of thumbnail. By default, it is 150px. * `width` Integer - The width of thumbnail. By default, it is 150px.
* `height` Integer - The height of thumbnail. By default, it is 150px. * `height` Integer - The height of thumbnail. By default, it is 150px.
`callback` Function - `function(sources) {}` `callback` Function - `function(error, sources) {}`
* `Sources` Array - An array of Source * `error` Error
* `sources` Array - An array of Source
Gets all desktop sources. Gets all desktop sources.