Simplify the desktopCapturer code
authorCheng Zhao <zcbenz@gmail.com>
Tue, 8 Dec 2015 05:49:26 +0000 (13:49 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Tue, 8 Dec 2015 05:49:26 +0000 (13:49 +0800)
atom/browser/api/atom_api_desktop_capturer.cc
atom/browser/api/atom_api_desktop_capturer.h
atom/browser/lib/desktop-capturer.coffee
atom/renderer/api/lib/desktop-capturer.coffee
chromium_src/chrome/browser/media/desktop_media_list.h
chromium_src/chrome/browser/media/native_desktop_media_list.cc
chromium_src/chrome/browser/media/native_desktop_media_list.h

index 21e98fe..ceb69de 100644 (file)
@@ -10,7 +10,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/media/desktop_media_list.h"
 #include "native_mate/dictionary.h"
-#include "native_mate/handle.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
@@ -38,45 +37,15 @@ namespace atom {
 
 namespace api {
 
-namespace {
-const int kThumbnailWidth = 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
-
 DesktopCapturer::DesktopCapturer() {
 }
 
 DesktopCapturer::~DesktopCapturer() {
 }
 
-void DesktopCapturer::StartHandling(const mate::Dictionary& args) {
-  bool show_screens = false;
-  bool show_windows = false;
-  if (!GetCapturerTypes(args, &show_windows, &show_screens)) {
-    Emit("handling-finished",
-         "Invalid options.",
-         std::vector<DesktopMediaList::Source>());
-    return;
-  }
-
+void DesktopCapturer::StartHandling(bool capture_window,
+                                    bool capture_screen,
+                                    const gfx::Size& thumbnail_size) {
   webrtc::DesktopCaptureOptions options =
       webrtc::DesktopCaptureOptions::CreateDefault();
 
@@ -91,15 +60,12 @@ void DesktopCapturer::StartHandling(const mate::Dictionary& args) {
 #endif
 
   scoped_ptr<webrtc::ScreenCapturer> screen_capturer(
-      show_screens ? webrtc::ScreenCapturer::Create(options) : nullptr);
+      capture_screen ? webrtc::ScreenCapturer::Create(options) : nullptr);
   scoped_ptr<webrtc::WindowCapturer> window_capturer(
-      show_windows ? webrtc::WindowCapturer::Create(options) : nullptr);
+      capture_window ? webrtc::WindowCapturer::Create(options) : nullptr);
   media_list_.reset(new NativeDesktopMediaList(screen_capturer.Pass(),
       window_capturer.Pass()));
 
-  gfx::Size thumbnail_size(kThumbnailWidth, kThumbnailHeight);
-  args.Get("thumbnailSize", &thumbnail_size);
-
   media_list_->SetThumbnailSize(thumbnail_size);
   media_list_->StartUpdating(this);
 }
@@ -120,11 +86,8 @@ void DesktopCapturer::OnSourceThumbnailChanged(int index) {
 }
 
 bool DesktopCapturer::OnRefreshFinished() {
-  std::vector<DesktopMediaList::Source> sources;
-  for (int i = 0; i < media_list_->GetSourceCount(); ++i)
-    sources.push_back(media_list_->GetSource(i));
+  Emit("finished", media_list_->GetSources());
   media_list_.reset();
-  Emit("handling-finished", "", sources);
   return false;
 }
 
index 32687ab..c22c8a4 100644 (file)
@@ -5,19 +5,11 @@
 #ifndef ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
 #define ATOM_BROWSER_API_ATOM_API_DESKTOP_CAPTURER_H_
 
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
 #include "atom/browser/api/event_emitter.h"
 #include "chrome/browser/media/desktop_media_list_observer.h"
 #include "chrome/browser/media/native_desktop_media_list.h"
 #include "native_mate/handle.h"
 
-namespace mate {
-class Dictionary;
-}
-
 namespace atom {
 
 namespace api {
@@ -27,7 +19,9 @@ class DesktopCapturer: public mate::EventEmitter,
  public:
   static mate::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
 
-  void StartHandling(const mate::Dictionary& args);
+  void StartHandling(bool capture_window,
+                     bool capture_screen,
+                     const gfx::Size& thumbnail_size);
 
  protected:
   DesktopCapturer();
index 8ef3389..a7fb29f 100644 (file)
@@ -7,31 +7,31 @@ deepEqual = (opt1, opt2) ->
 # A queue for holding all requests from renderer process.
 requestsQueue = []
 
-ipcMain.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, options, id) ->
-  request = { id: id, options: options, webContents: event.sender }
+ipcMain.on 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', (event, captureWindow, captureScreen, thumbnailSize, id) ->
+  request = id: id, options: {captureWindow, captureScreen, thumbnailSize}, webContents: event.sender
   requestsQueue.push request
-  desktopCapturer.startHandling options if requestsQueue.length is 1
+  desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize if requestsQueue.length is 1
   # If the WebContents is destroyed before receiving result, just remove the
   # reference from requestsQueue to make the module not send the result to it.
-  event.sender.once 'destroyed', () ->
+  event.sender.once 'destroyed', ->
     request.webContents = null
 
-desktopCapturer.emit = (event_name, event, error_message, sources) ->
+desktopCapturer.emit = (event, name, sources) ->
   # Receiving sources result from main process, now send them back to renderer.
   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)
-  handledRequest.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{handledRequest.id}", error_message, result
+  handledRequest.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{handledRequest.id}", result
 
   # Check the queue to see whether there is other same request. If has, handle
   # it for reducing redunplicated `desktopCaptuer.startHandling` calls.
   unhandledRequestsQueue = []
   for request in requestsQueue
     if deepEqual handledRequest.options, request.options
-      request.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{request.id}", error_message, result
+      request.webContents?.send "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{request.id}", errorMessage, result
     else
       unhandledRequestsQueue.push request
   requestsQueue = unhandledRequestsQueue
   # If the requestsQueue is not empty, start a new request handling.
   if requestsQueue.length > 0
-    desktopCapturer.startHandling requestsQueue[0].options
+    {captureWindow, captureScreen, thumbnailSize} = requestsQueue[0].options
+    desktopCapturer.startHandling captureWindow, captureScreen, thumbnailSize
index fc4118f..7c7c898 100644 (file)
@@ -1,11 +1,20 @@
-{ipcRenderer, NativeImage} = require 'electron'
+{ipcRenderer, nativeImage} = require 'electron'
 
 nextId = 0
 getNextId = -> ++nextId
 
+# |options.type| can not be empty and has to include 'window' or 'screen'.
+isValid = (options) ->
+  return options?.types? and Array.isArray options.types
+
 exports.getSources = (options, callback) ->
+  return callback new Error('Invalid options') unless isValid options
+
+  captureWindow = 'window' in options.types
+  captureScreen = 'screen' in options.types
+  options.thumbnailSize ?= width: 150, height: 150
+
   id = getNextId()
-  ipcRenderer.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', options, id
-  ipcRenderer.once "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{id}", (error_message, 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)
+  ipcRenderer.send 'ATOM_BROWSER_DESKTOP_CAPTURER_GET_SOURCES', captureWindow, captureScreen, options.thumbnailSize, id
+  ipcRenderer.once "ATOM_RENDERER_DESKTOP_CAPTURER_RESULT_#{id}", (event, sources) ->
+    callback null, ({id: source.id, name: source.name, thumbnail: nativeImage.createFromDataURL source.thumbnail} for source in sources)
index 44850bd..7ef703e 100644 (file)
@@ -56,6 +56,7 @@ class DesktopMediaList {
 
   virtual int GetSourceCount() const = 0;
   virtual const Source& GetSource(int index) const = 0;
+  virtual std::vector<Source> GetSources() const = 0;
 };
 
 #endif  // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_LIST_H_
index 2464aec..4a7fb58 100644 (file)
@@ -282,6 +282,10 @@ const DesktopMediaList::Source& NativeDesktopMediaList::GetSource(
   return sources_[index];
 }
 
+std::vector<DesktopMediaList::Source> NativeDesktopMediaList::GetSources() const {
+  return sources_;
+}
+
 void NativeDesktopMediaList::Refresh() {
   capture_task_runner_->PostTask(
       FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
index 81bd321..943d3dd 100644 (file)
@@ -36,6 +36,7 @@ class NativeDesktopMediaList : public DesktopMediaList {
   void StartUpdating(DesktopMediaListObserver* observer) override;
   int GetSourceCount() const override;
   const Source& GetSource(int index) const override;
+  std::vector<Source> GetSources() const override;
   void SetViewDialogWindowId(content::DesktopMediaID::Id dialog_id) override;
 
  private: