void (@Nullable Project project, @NotNull Disposable lifetime, @NotNull ModalityState callbackModality, @NotNull DetectedSdkListener listener) { ApplicationManager.getApplication().assertWriteIntentLockAcquired(); if (!isDetectorEnabled()) { return; } /* TODO[jo] fix: deadlock in combobox tests on {@link SdkDetector#myPublicationLock} detection must be called from edt {@link SdkDetector#getDetectedSdksWithUpdate} detection is synchronous for unit tests {@link com.intellij.openapi.progress.impl.CoreProgressManager#run} */ Application application = ApplicationManager.getApplication(); if (application.isUnitTestMode() || application.isHeadlessEnvironment()) { LOG.warn("Sdks detection is skipped, because deadlock is coming for synchronous detection"); return; } EdtDetectedSdkListener actualListener = new EdtDetectedSdkListener(callbackModality, listener); synchronized (myPublicationLock) { //skip multiple registrations if (!myListeners.add(actualListener)) return; //it there is no other listeners, let's refresh if (myListeners.size() <= 1 && myIsRunning.compareAndSet(false, true)) { myDetectedResults.clear(); /* * We haven't status bar when project isn't opened (Welcome screen settings, structure for new projects, new project wizard, etc.) * In these cases any execution with indicator shows progress in modal dialog. * What closes sdk combobox popup (Now getDetectedSdksWithUpdate is used only from sdk combo-box model.) * But also, sdk combo-box have build-in sdk detection progress indicator. * So we don't need explicit background task with progress indication in this case. */ BackgroundTaskUtil.executeOnPooledThread(lifetime, () -> { var progressIndicator = ProgressManager.getInstance().getProgressIndicator(); detectAllSdks(progressIndicator, myMulticaster); }); } //deliver everything we have myDetectedResults.forEach(result -> result.accept(listener)); } Disposer.register(lifetime, () -> myListeners.remove(actualListener)); }