Skip to content

Commit 86c452d

Browse files
committed
Edge: properly handle initialization failures and abortion
There is currently only few handling for failures during initialization of an Edge browser / WebView instance. The Microsoft documentation provides further information on this, in particular: - ERROR_INVALID_STATE indicates that multiple Edge instances with the same data folder but different environment options exist - E_ABORT indicates an active abortion of the initialization process - On any other non-OK return value than the above ones, the app should retry initialization of the instance This change adds appropriate handling for these scenarios, consisting of uniform rollback logic when the initialization fails or is aborted and retry logic to make repeated creation attempts.
1 parent c39b59c commit 86c452d

File tree

4 files changed

+44
-18
lines changed

4 files changed

+44
-18
lines changed

bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
309309
return webView;
310310
}
311311

312+
private void abortInitialization() {
313+
webViewFuture.cancel(true);
314+
}
315+
312316
private void initializeWebView_2(ICoreWebView2 webView) {
313317
long[] ppv = new long[1];
314318
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_2, ppv);
@@ -567,35 +571,55 @@ private String getDataDir(Display display) {
567571

568572
@Override
569573
public void create(Composite parent, int style) {
574+
createInstance();
575+
}
576+
577+
private void createInstance() {
570578
containingEnvironment = createEnvironment();
571579
long[] ppv = new long[1];
572580
int hr = containingEnvironment.environment().QueryInterface(COM.IID_ICoreWebView2Environment2, ppv);
573581
if (hr == COM.S_OK) environment2 = new ICoreWebView2Environment2(ppv[0]);
574582
// The webview calls are queued to be executed when it is done executing the current task.
575-
IUnknown setupBrowserCallback = newCallback((result, pv) -> {
576-
if ((int)result == COM.S_OK) {
583+
containingEnvironment.environment().CreateCoreWebView2Controller(browser.handle, controllerInitializedCallback());
584+
}
585+
586+
private IUnknown controllerInitializedCallback() {
587+
return newCallback((result, pv) -> {
588+
Runnable rollbackInitialization = () -> {
589+
webViewProvider.abortInitialization();
590+
if (environment2 != null) {
591+
environment2.Release();
592+
}
593+
};
594+
if (browser.isDisposed()) {
595+
rollbackInitialization.run();
596+
}
597+
if (result == OS.HRESULT_FROM_WIN32(OS.ERROR_INVALID_STATE)) {
598+
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
599+
" Edge instance with same data folder but different environment options already exists");
600+
}
601+
switch ((int) result) {
602+
case COM.S_OK:
577603
new IUnknown(pv).AddRef();
604+
setupBrowser((int) result, pv);
605+
break;
606+
case COM.E_WRONG_THREAD:
607+
error(SWT.ERROR_THREAD_INVALID_ACCESS, (int) result);
608+
break;
609+
case COM.E_ABORT:
610+
rollbackInitialization.run();
611+
break;
612+
default:
613+
System.err.println("Edge initialization failed, retrying");
614+
rollbackInitialization.run();
615+
createInstance();
616+
break;
578617
}
579-
setupBrowser((int)result, pv);
580618
return COM.S_OK;
581619
});
582-
containingEnvironment.environment().CreateCoreWebView2Controller(browser.handle, setupBrowserCallback);
583620
}
584621

585622
void setupBrowser(int hr, long pv) {
586-
if(browser.isDisposed()) {
587-
browserDispose(new Event());
588-
return;
589-
}
590-
switch (hr) {
591-
case COM.S_OK:
592-
break;
593-
case COM.E_WRONG_THREAD:
594-
error(SWT.ERROR_THREAD_INVALID_ACCESS, hr);
595-
break;
596-
default:
597-
error(SWT.ERROR_NO_HANDLES, hr);
598-
}
599623
long[] ppv = new long[] {pv};
600624
controller = new ICoreWebView2Controller(ppv[0]);
601625
final ICoreWebView2 webView = webViewProvider.initializeWebView(controller);

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ public class COM extends OS {
183183
public static final int DV_E_STGMEDIUM = -2147221402;
184184
public static final int DV_E_TYMED = -2147221399;
185185
public static final int DVASPECT_CONTENT = 1;
186+
public static final int E_ABORT = 0x80004004;
186187
public static final int E_ACCESSDENIED = 0x80070005;
187188
public static final int E_FAIL = -2147467259;
188189
public static final int E_INVALIDARG = -2147024809;

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ public class OS extends C {
456456
public static final int EN_CHANGE = 0x300;
457457
public static final int EP_EDITTEXT = 1;
458458
public static final int ERROR_FILE_NOT_FOUND = 0x2;
459+
public static final int ERROR_INVALID_STATE = 0x139F;
459460
public static final int ERROR_NO_MORE_ITEMS = 0x103;
460461
public static final int ERROR_CANCELED = 0x4C7;
461462
public static final int ESB_DISABLE_BOTH = 0x3;

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public static Collection<Object[]> browserFlagsToTest() {
145145
if (SwtTestUtil.isWindows) {
146146
// NOTE: This is currently disabled due to test issues in the CI
147147
// Execute Edge tests first, because IE starts some OS timer that conflicts with Edge event handling
148-
// browserFlags.add(0, new Object[] {SWT.EDGE});
148+
browserFlags.add(0, new Object[] {SWT.EDGE});
149149
}
150150
browserFlags.add(new Object[] {SWT.NONE});
151151
return browserFlags;

0 commit comments

Comments
 (0)