@@ -287,149 +287,161 @@ static int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
287287 return phr [0 ];
288288}
289289
290- class WebViewProvider {
290+ class WebViewWrapper {
291+ private ICoreWebView2 webView ;
292+ private ICoreWebView2_2 webView_2 ;
293+ private ICoreWebView2_10 webView_10 ;
294+ private ICoreWebView2_11 webView_11 ;
295+ private ICoreWebView2_12 webView_12 ;
296+ private ICoreWebView2_13 webView_13 ;
297+ }
291298
292- private CompletableFuture <ICoreWebView2 > webViewFuture = new CompletableFuture <>();
293- private CompletableFuture <ICoreWebView2_2 > webView_2Future = new CompletableFuture <>();
294- private CompletableFuture <ICoreWebView2_10 > webView_10Future = new CompletableFuture <>();
295- private CompletableFuture <ICoreWebView2_11 > webView_11Future = new CompletableFuture <>();
296- private CompletableFuture <ICoreWebView2_12 > webView_12Future = new CompletableFuture <>();
297- private CompletableFuture <ICoreWebView2_13 > webView_13Future = new CompletableFuture <>();
299+ class WebViewProvider {
298300
299- private CompletableFuture <Void > lastWebViewTask = webViewFuture .thenRun (() -> {});
301+ private CompletableFuture <WebViewWrapper > webViewWrapperFuture = initializeWebViewFutureWithTimeOut ();
302+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
300303
301304 ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
302305 long [] ppv = new long [1 ];
303306 controller .get_CoreWebView2 (ppv );
304307 final ICoreWebView2 webView = new ICoreWebView2 (ppv [0 ]);
305- initializeWebView_2 (webView );
306- initializeWebView_10 (webView );
307- initializeWebView_11 (webView );
308- initializeWebView_12 (webView );
309- initializeWebView_13 (webView );
310- webViewFuture .complete (webView );
308+ final WebViewWrapper webViewWrapper = new WebViewWrapper ();
309+ webViewWrapper .webView = webView ;
310+ webViewWrapper .webView_2 = initializeWebView_2 (webView );
311+ webViewWrapper .webView_10 = initializeWebView_10 (webView );
312+ webViewWrapper .webView_11 = initializeWebView_11 (webView );
313+ webViewWrapper .webView_12 = initializeWebView_12 (webView );
314+ webViewWrapper .webView_13 = initializeWebView_13 (webView );
315+ webViewWrapperFuture .complete (webViewWrapper );
311316 return webView ;
312317 }
313318
319+ private CompletableFuture <WebViewWrapper > initializeWebViewFutureWithTimeOut () {
320+ CompletableFuture <WebViewWrapper > webViewWrapperFuture = new CompletableFuture <>();
321+ webViewWrapperFuture .orTimeout (3 , TimeUnit .MILLISECONDS ).exceptionally (exception -> {
322+ releaseEnvironment ();
323+ // Throw exception on the Display thread directly to prevent CompletableFuture
324+ // to wrap the exception and throw it silently
325+ browser .getDisplay ().execute (() -> SWT .error (SWT .ERROR_UNSPECIFIED , exception , "Edge Browser initialization timed out" ));
326+ return null ;
327+ });
328+ return webViewWrapperFuture ;
329+ }
330+
314331 private void abortInitialization () {
315- webViewFuture .cancel (true );
332+ webViewWrapperFuture .cancel (true );
316333 }
317334
318- private void initializeWebView_2 (ICoreWebView2 webView ) {
335+ private ICoreWebView2_2 initializeWebView_2 (ICoreWebView2 webView ) {
319336 long [] ppv = new long [1 ];
320337 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_2 , ppv );
321338 if (hr == COM .S_OK ) {
322- webView_2Future .complete (new ICoreWebView2_2 (ppv [0 ]));
323- } else {
324- webView_2Future .cancel (true );
339+ return new ICoreWebView2_2 (ppv [0 ]);
325340 }
341+ return null ;
326342 }
327343
328- private void initializeWebView_10 (ICoreWebView2 webView ) {
344+ private ICoreWebView2_10 initializeWebView_10 (ICoreWebView2 webView ) {
329345 long [] ppv = new long [1 ];
330346 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_10 , ppv );
331347 if (hr == COM .S_OK ) {
332- webView_10Future .complete (new ICoreWebView2_10 (ppv [0 ]));
333- } else {
334- webView_10Future .cancel (true );
348+ return new ICoreWebView2_10 (ppv [0 ]);
335349 }
350+ return null ;
336351 }
337352
338- private void initializeWebView_11 (ICoreWebView2 webView ) {
353+ private ICoreWebView2_11 initializeWebView_11 (ICoreWebView2 webView ) {
339354 long [] ppv = new long [1 ];
340355 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_11 , ppv );
341356 if (hr == COM .S_OK ) {
342- webView_11Future .complete (new ICoreWebView2_11 (ppv [0 ]));
343- } else {
344- webView_11Future .cancel (true );
357+ return new ICoreWebView2_11 (ppv [0 ]);
345358 }
359+ return null ;
346360 }
347361
348- private void initializeWebView_12 (ICoreWebView2 webView ) {
362+ private ICoreWebView2_12 initializeWebView_12 (ICoreWebView2 webView ) {
349363 long [] ppv = new long [1 ];
350364 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_12 , ppv );
351365 if (hr == COM .S_OK ) {
352- webView_12Future .complete (new ICoreWebView2_12 (ppv [0 ]));
353- } else {
354- webView_12Future .cancel (true );
366+ return new ICoreWebView2_12 (ppv [0 ]);
355367 }
368+ return null ;
356369 }
357370
358- private void initializeWebView_13 (ICoreWebView2 webView ) {
371+ private ICoreWebView2_13 initializeWebView_13 (ICoreWebView2 webView ) {
359372 long [] ppv = new long [1 ];
360373 int hr = webView .QueryInterface (COM .IID_ICoreWebView2_13 , ppv );
361374 if (hr == COM .S_OK ) {
362- webView_13Future .complete (new ICoreWebView2_13 (ppv [0 ]));
363- } else {
364- webView_13Future .cancel (true );
375+ return new ICoreWebView2_13 (ppv [0 ]);
365376 }
377+ return null ;
366378 }
367379
368380 ICoreWebView2 getWebView (boolean waitForPendingWebviewTasksToFinish ) {
369381 if (waitForPendingWebviewTasksToFinish ) {
370382 waitForFutureToFinish (lastWebViewTask );
371383 }
372- return webViewFuture .join ();
384+ return webViewWrapperFuture .join (). webView ;
373385 }
374386
375387 ICoreWebView2_2 getWebView_2 (boolean waitForPendingWebviewTasksToFinish ) {
376388 if (waitForPendingWebviewTasksToFinish ) {
377389 waitForFutureToFinish (lastWebViewTask );
378390 }
379- return webView_2Future .join ();
391+ return webViewWrapperFuture .join (). webView_2 ;
380392 }
381393
382394 boolean isWebView_2Available () {
383- waitForFutureToFinish (webView_2Future );
384- return ! webView_2Future . isCancelled () ;
395+ waitForFutureToFinish (webViewWrapperFuture );
396+ return webViewWrapperFuture . join (). webView_2 != null ;
385397 }
386398
387399 ICoreWebView2_10 getWebView_10 (boolean waitForPendingWebviewTasksToFinish ) {
388400 if (waitForPendingWebviewTasksToFinish ) {
389401 waitForFutureToFinish (lastWebViewTask );
390402 }
391- return webView_10Future .join ();
403+ return webViewWrapperFuture .join (). webView_10 ;
392404 }
393405
394406 boolean isWebView_10Available () {
395- waitForFutureToFinish (webView_10Future );
396- return ! webView_10Future . isCancelled () ;
407+ waitForFutureToFinish (webViewWrapperFuture );
408+ return webViewWrapperFuture . join (). webView_10 != null ;
397409 }
398410
399411 ICoreWebView2_11 getWebView_11 (boolean waitForPendingWebviewTasksToFinish ) {
400412 if (waitForPendingWebviewTasksToFinish ) {
401413 waitForFutureToFinish (lastWebViewTask );
402414 }
403- return webView_11Future .join ();
415+ return webViewWrapperFuture .join (). webView_11 ;
404416 }
405417
406418 boolean isWebView_11Available () {
407- waitForFutureToFinish (webView_11Future );
408- return ! webView_11Future . isCancelled () ;
419+ waitForFutureToFinish (webViewWrapperFuture );
420+ return webViewWrapperFuture . join (). webView_11 != null ;
409421 }
410422
411423 ICoreWebView2_12 getWebView_12 (boolean waitForPendingWebviewTasksToFinish ) {
412424 if (waitForPendingWebviewTasksToFinish ) {
413425 waitForFutureToFinish (lastWebViewTask );
414426 }
415- return webView_12Future .join ();
427+ return webViewWrapperFuture .join (). webView_12 ;
416428 }
417429
418430 boolean isWebView_12Available () {
419- waitForFutureToFinish (webView_12Future );
420- return ! webView_12Future . isCancelled () ;
431+ waitForFutureToFinish (webViewWrapperFuture );
432+ return webViewWrapperFuture . join (). webView_12 != null ;
421433 }
422434
423435 ICoreWebView2_13 getWebView_13 (boolean waitForPendingWebviewTasksToFinish ) {
424436 if (waitForPendingWebviewTasksToFinish ) {
425437 waitForFutureToFinish (lastWebViewTask );
426438 }
427- return webView_13Future .join ();
439+ return webViewWrapperFuture .join (). webView_13 ;
428440 }
429441
430442 boolean isWebView_13Available () {
431- waitForFutureToFinish (webView_13Future );
432- return ! webView_13Future . isCancelled () ;
443+ waitForFutureToFinish (webViewWrapperFuture );
444+ return webViewWrapperFuture . join (). webView_13 != null ;
433445 }
434446
435447 /*
@@ -587,21 +599,13 @@ private void createInstance(int previousAttempts) {
587599}
588600
589601private IUnknown createControllerInitializationCallback (int previousAttempts ) {
590- Runnable initializationRollback = () -> {
591- webViewProvider .abortInitialization ();
592- if (environment2 != null ) {
593- environment2 .Release ();
594- environment2 = null ;
595- }
596- containingEnvironment .instances ().remove (this );
597- };
598602 return newCallback ((result , pv ) -> {
599603 if (browser .isDisposed ()) {
600- initializationRollback . run ();
604+ rollbackInitialization ();
601605 return COM .S_OK ;
602606 }
603607 if (result == OS .HRESULT_FROM_WIN32 (OS .ERROR_INVALID_STATE )) {
604- initializationRollback . run ();
608+ rollbackInitialization ();
605609 SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
606610 " Edge instance with same data folder but different environment options already exists" );
607611 }
@@ -611,14 +615,14 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
611615 setupBrowser ((int ) result , pv );
612616 break ;
613617 case COM .E_WRONG_THREAD :
614- initializationRollback . run ();
618+ rollbackInitialization ();
615619 error (SWT .ERROR_THREAD_INVALID_ACCESS , (int ) result );
616620 break ;
617621 case COM .E_ABORT :
618- initializationRollback . run ();
622+ rollbackInitialization ();
619623 break ;
620624 default :
621- initializationRollback . run ();
625+ rollbackInitialization ();
622626 if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
623627 System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
624628 createInstance (previousAttempts + 1 );
@@ -632,6 +636,19 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
632636 });
633637}
634638
639+ private void rollbackInitialization () {
640+ webViewProvider .abortInitialization ();
641+ releaseEnvironment ();
642+ }
643+
644+ private void releaseEnvironment () {
645+ if (environment2 != null ) {
646+ environment2 .Release ();
647+ environment2 = null ;
648+ }
649+ containingEnvironment .instances ().remove (this );
650+ }
651+
635652void setupBrowser (int hr , long pv ) {
636653 long [] ppv = new long [] {pv };
637654 controller = new ICoreWebView2Controller (ppv [0 ]);
0 commit comments