refactor: ginify desktopCapturer (#22746)

This commit is contained in:
Jeremy Apthorp 2020-03-19 11:35:11 -07:00 committed by GitHub
parent 9aa27e1709
commit a824e12275
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 28 deletions

View file

@ -1,5 +1,3 @@
import { EventEmitter } from 'events'
const { createDesktopCapturer } = process.electronBinding('desktop_capturer')
const deepEqual = (a: ElectronInternal.GetSourcesOptions, b: ElectronInternal.GetSourcesOptions) => JSON.stringify(a) === JSON.stringify(b)
@ -23,21 +21,20 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
const stopRunning = () => {
if (capturer) {
capturer.emit = null
delete capturer._onerror
delete capturer._onfinished
capturer = null
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter(running => running.options !== options)
}
const emitter = new EventEmitter()
emitter.once('error', (event, error: string) => {
capturer._onerror = (error: string) => {
stopRunning()
reject(error)
})
}
emitter.once('finished', (event, sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
capturer._onfinished = (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => {
stopRunning()
resolve(sources.map(source => ({
id: source.id,
@ -46,9 +43,8 @@ export const getSources = (event: Electron.IpcMainEvent, options: ElectronIntern
display_id: source.display_id,
appIcon: (fetchWindowIcons && source.appIcon) ? source.appIcon.toDataURL() : null
})))
})
}
capturer.emit = emitter.emit.bind(emitter)
capturer.startHandling(options.captureWindow, options.captureScreen, options.thumbnailSize, options.fetchWindowIcons)
// If the WebContents is destroyed before receiving result, just remove the

View file

@ -14,10 +14,11 @@
#include "chrome/browser/media/webrtc/desktop_media_list.h"
#include "chrome/browser/media/webrtc/window_icon_util.h"
#include "content/public/browser/desktop_capture.h"
#include "gin/object_template_builder.h"
#include "shell/common/api/electron_api_native_image.h"
#include "shell/common/gin_converters/gfx_converter.h"
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/object_template_builder.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/node_includes.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
@ -59,9 +60,9 @@ namespace electron {
namespace api {
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {
Init(isolate);
}
gin::WrapperInfo DesktopCapturer::kWrapperInfo = {gin::kEmbedderNativeGin};
DesktopCapturer::DesktopCapturer(v8::Isolate* isolate) {}
DesktopCapturer::~DesktopCapturer() = default;
@ -154,7 +155,7 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
// |media_list_sources|.
if (!webrtc::DxgiDuplicatorController::Instance()->GetDeviceNames(
&device_names)) {
Emit("error", "Failed to get sources.");
gin_helper::CallMethod(this, "_onerror", "Failed to get sources.");
return;
}
@ -184,7 +185,8 @@ void DesktopCapturer::UpdateSourcesList(DesktopMediaList* list) {
}
if (!capture_window_ && !capture_screen_)
Emit("finished", captured_sources_, fetch_window_icons_);
gin_helper::CallMethod(this, "_onfinished", captured_sources_,
fetch_window_icons_);
}
// static
@ -192,15 +194,16 @@ gin::Handle<DesktopCapturer> DesktopCapturer::Create(v8::Isolate* isolate) {
return gin::CreateHandle(isolate, new DesktopCapturer(isolate));
}
// static
void DesktopCapturer::BuildPrototype(
v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype) {
prototype->SetClassName(gin::StringToV8(isolate, "DesktopCapturer"));
gin_helper::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
gin::ObjectTemplateBuilder DesktopCapturer::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<DesktopCapturer>::GetObjectTemplateBuilder(isolate)
.SetMethod("startHandling", &DesktopCapturer::StartHandling);
}
const char* DesktopCapturer::GetTypeName() {
return "DesktopCapturer";
}
} // namespace api
} // namespace electron

View file

@ -12,13 +12,13 @@
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "gin/handle.h"
#include "shell/common/gin_helper/trackable_object.h"
#include "gin/wrappable.h"
namespace electron {
namespace api {
class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
class DesktopCapturer : public gin::Wrappable<DesktopCapturer>,
public DesktopMediaListObserver {
public:
struct Source {
@ -32,14 +32,17 @@ class DesktopCapturer : public gin_helper::TrackableObject<DesktopCapturer>,
static gin::Handle<DesktopCapturer> Create(v8::Isolate* isolate);
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
void StartHandling(bool capture_window,
bool capture_screen,
const gfx::Size& thumbnail_size,
bool fetch_window_icons);
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
const char* GetTypeName() override;
protected:
explicit DesktopCapturer(v8::Isolate* isolate);
~DesktopCapturer() override;

View file

@ -9,6 +9,7 @@
#include <vector>
#include "gin/converter.h"
#include "gin/wrappable.h"
namespace gin_helper {
@ -63,6 +64,28 @@ v8::Local<v8::Value> CustomEmit(v8::Isolate* isolate,
&converted_args);
}
template <typename T, typename... Args>
v8::Local<v8::Value> CallMethod(v8::Isolate* isolate,
gin::Wrappable<T>* object,
const char* method_name,
Args&&... args) {
v8::HandleScope scope(isolate);
v8::Local<v8::Object> v8_object;
if (object->GetWrapper(isolate).ToLocal(&v8_object))
return CustomEmit(isolate, v8_object, method_name,
std::forward<Args>(args)...);
else
return v8::Local<v8::Value>();
}
template <typename T, typename... Args>
v8::Local<v8::Value> CallMethod(gin::Wrappable<T>* object,
const char* method_name,
Args&&... args) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
return CallMethod(isolate, object, method_name, std::forward<Args>(args)...);
}
} // namespace gin_helper
#endif // SHELL_COMMON_GIN_HELPER_EVENT_EMITTER_CALLER_H_

View file

@ -94,7 +94,8 @@ declare namespace ElectronInternal {
interface DesktopCapturer {
startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void;
emit: typeof NodeJS.EventEmitter.prototype.emit | null;
_onerror: (error: string) => void;
_onfinished: (sources: Electron.DesktopCapturerSource[], fetchWindowIcons: boolean) => void;
}
interface GetSourcesOptions {