UsageView (UsageTarget @NotNull [] searchFor, @NotNull Factory<? extends UsageSearcher> searcherFactory, @NotNull UsageViewPresentation presentation, @NotNull FindUsagesProcessPresentation processPresentation, @Nullable UsageViewStateListener listener) { if (ApplicationManager.getApplication().isWriteAccessAllowed()) { throw new IllegalStateException("Can't start find usages from under write action. Please consider Application.invokeLater() it instead."); } Supplier<SearchScope> scopeSupplier = getMaxSearchScopeToWarnOfFallingOutOf(searchFor); AtomicReference<UsageViewEx> usageViewRef = new AtomicReference<>(); long start = System.nanoTime(); AtomicLong firstItemFoundTS = new AtomicLong(); AtomicBoolean tooManyUsages = new AtomicBoolean(); Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) { @Override public void run(@NotNull ProgressIndicator indicator) { SearchScope searchScopeToWarnOfFallingOutOf = ReadAction.compute(() -> scopeSupplier.get()); new SearchForUsagesRunnable(UsageViewManagerImpl.this, UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory, processPresentation, searchScopeToWarnOfFallingOutOf, listener, firstItemFoundTS, tooManyUsages).run(); } @Override public void onCancel() { reportSearchCompletedToFus(true); super.onCancel(); } @NotNull @Override public NotificationInfo getNotificationInfo() { UsageViewEx usageView = usageViewRef.get(); int count = usageView == null ? 0 : usageView.getUsagesCount(); long duration = reportSearchCompletedToFus(false); String notification = StringUtil.capitalizeWords(UsageViewBundle.message("usages.n", count), true); LOG.debug(notification + " in " + duration + "ms."); return new NotificationInfo("Find Usages", UsageViewBundle.message("notification.title.find.usages.finished"), notification); } private long reportSearchCompletedToFus(boolean isCancelled) { long currentTS = System.nanoTime(); long durationFirstResults = TimeUnit.NANOSECONDS.toMillis(firstItemFoundTS.get() - start); long duration = TimeUnit.NANOSECONDS.toMillis(currentTS - start); PsiElement element = SearchForUsagesRunnable.getPsiElement(searchFor); UsageViewEx view = usageViewRef.get(); Class<? extends PsiElement> targetClass = element != null ? element.getClass() : null; Language language = element != null ? ReadAction.compute(element::getLanguage) : null; SearchScope scope = null; if (element instanceof DataProvider) { scope = UsageView.USAGE_SCOPE.getData((DataProvider)element); } int numberOfUsagesFound = view == null ? 0 : view.getUsagesCount(); UsageViewStatisticsCollector.logSearchFinished(myProject, view, targetClass, scope, language, numberOfUsagesFound, durationFirstResults, duration, tooManyUsages.get(), isCancelled, CodeNavigateSource.FindToolWindow); return duration; } }; ProgressManager.getInstance().run(task); return usageViewRef.get(); }