refactor: ginify desktopCapturer (#22746)
This commit is contained in:
		
					parent
					
						
							
								9aa27e1709
							
						
					
				
			
			
				commit
				
					
						a824e12275
					
				
			
		
					 5 changed files with 54 additions and 28 deletions
				
			
		|  | @ -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
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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_
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								typings/internal-electron.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								typings/internal-electron.d.ts
									
										
									
									
										vendored
									
									
								
							|  | @ -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 { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Apthorp
				Jeremy Apthorp