tmf: Include requested_marker_categories when fetching annotations

Do not include the hidden categories in the annotations request. This
can avoid unnecessary computations when a category is hidden.

Add interface to trigger fetching of annotations when the visible
categories have changed.

[Fixed] Include requested_marker_categories when fetching annotations
[Added] ITimeGraphMarkerListener to trigger refresh of annotations

Change-Id: I1e0ad05b673412cf6b4cf06c79571a63333464ef
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/182459
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/ResourcesViewTest.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/ResourcesViewTest.java
index 455eb84..43284da 100644
--- a/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/ResourcesViewTest.java
+++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/ResourcesViewTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015, 2018 Ericsson and others
+ * Copyright (c) 2015, 2021 Ericsson and others
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License 2.0 which
@@ -480,7 +480,7 @@
 
         /* show Lost Events markers */
         viewBot.viewMenu(LOST_EVENTS).click();
-        assertEquals(size1, getSize(markerAxis));
+        SWTBotUtils.waitUntil(ma -> size1.equals(getSize(ma)), markerAxis, "Lost Events did not reappear");
     }
 
     /**
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF b/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
index 28160c7..7a5677a 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 7.0.0.qualifier
+Bundle-Version: 7.1.0.qualifier
 Bundle-Localization: plugin
 Bundle-SymbolicName: org.eclipse.tracecompass.tmf.ui;singleton:=true
 Bundle-Activator: org.eclipse.tracecompass.internal.tmf.ui.Activator
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/pom.xml b/tmf/org.eclipse.tracecompass.tmf.ui/pom.xml
index ae27e98..086fe00 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/pom.xml
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/pom.xml
@@ -20,7 +20,7 @@
   </parent>
 
   <artifactId>org.eclipse.tracecompass.tmf.ui</artifactId>
-  <version>7.0.0-SNAPSHOT</version>
+  <version>7.1.0-SNAPSHOT</version>
 
   <packaging>eclipse-plugin</packaging>
 
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java
index dbd6ee4..aa93c43 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/AbstractTimeGraphView.java
@@ -236,12 +236,16 @@
 
         @Override
         public @NonNull List<@NonNull IMarkerEvent> getMarkerList(@NonNull String category, long startTime, long endTime, long resolution, @NonNull IProgressMonitor monitor) {
+            if (!getTimeGraphViewer().isMarkerCategoryVisible(category)) {
+                return Collections.emptyList();
+            }
 
             Map<@NonNull String, @NonNull Object> parameters = new HashMap<>();
             MarkerSet defaultMarkerSet = MarkerUtils.getDefaultMarkerSet();
             if (defaultMarkerSet != null) {
                 parameters.put(DataProviderParameterUtils.REQUESTED_MARKER_SET_KEY, defaultMarkerSet.getId());
             }
+            parameters.put(DataProviderParameterUtils.REQUESTED_MARKER_CATEGORIES_KEY, Collections.singletonList(category));
             parameters.put(DataProviderParameterUtils.REQUESTED_TRACE_KEY, fTrace.getHostId());
             parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, StateSystemUtils.getTimes(startTime, endTime, resolution));
             TmfModelResponse<@NonNull AnnotationModel> response = fProvider.fetchAnnotations(parameters, new NullProgressMonitor());
@@ -1486,6 +1490,8 @@
             }
         });
 
+        fTimeGraphViewer.addMarkerListener(() -> restartZoomThread());
+
         timeGraphControl.addPaintListener(new PaintListener() {
 
             /**
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
index 460be3f..01aa8fd 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/timegraph/BaseDataProviderTimeGraphView.java
@@ -129,9 +129,11 @@
     protected final Table<Object, Long, @NonNull TimeGraphEntry> fScopedEntries = HashBasedTable.create();
 
     /** Map of parent trace to providers */
-    private Multimap<ITmfTrace, ITimeGraphDataProvider<? extends @NonNull TimeGraphEntryModel>> fProviders = HashMultimap.create();
+    private final Multimap<ITmfTrace, ITimeGraphDataProvider<? extends @NonNull TimeGraphEntryModel>> fProviders = HashMultimap.create();
     /** Map of parent trace to scopes, for cleanup */
-    private Multimap<ITmfTrace, Object> fScopes = HashMultimap.create();
+    private final Multimap<ITmfTrace, Object> fScopes = HashMultimap.create();
+    /** Map of provider to marker categories */
+    private final Map<ITimeGraphDataProvider<? extends @NonNull TimeGraphEntryModel>, List<String>> fMarkerCategories = new HashMap<>();
 
     private final String fProviderId;
 
@@ -580,7 +582,9 @@
                 TmfModelResponse<@NonNull AnnotationCategoriesModel> response = ((IOutputAnnotationProvider) provider).fetchAnnotationCategories(parameters, new NullProgressMonitor());
                 AnnotationCategoriesModel model = response.getModel();
                 if (model != null) {
-                    viewMarkerCategories.addAll(model.getAnnotationCategories());
+                    List<@NonNull String> categories = model.getAnnotationCategories();
+                    viewMarkerCategories.addAll(categories);
+                    fMarkerCategories.put(provider, categories);
                 }
             }
         }
@@ -598,7 +602,13 @@
         Multimap<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Long> providersToModelIds = filterGroupEntries(entries, startTime, endTime);
         for (ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider : providersToModelIds.keySet()) {
             if (provider instanceof IOutputAnnotationProvider) {
+                List<String> categories = new ArrayList<>(fMarkerCategories.get(provider));
+                categories.removeIf(category -> !getTimeGraphViewer().isMarkerCategoryVisible(category));
+                if (categories.isEmpty()) {
+                    continue;
+                }
                 Map<@NonNull String, @NonNull Object> parameters = getFetchAnnotationsParameters(times, providersToModelIds.get(provider));
+                parameters.put(DataProviderParameterUtils.REQUESTED_MARKER_CATEGORIES_KEY, categories);
                 TmfModelResponse<@NonNull AnnotationModel> response = ((IOutputAnnotationProvider) provider).fetchAnnotations(parameters, new NullProgressMonitor());
                 AnnotationModel model = response.getModel();
                 if (model != null) {
@@ -773,6 +783,7 @@
                     fProviders.removeAll(viewTrace).forEach(provider -> {
                         fEntries.row(provider).clear();
                         fEntryIds.column(provider).clear();
+                        fMarkerCategories.remove(provider);
                     });
                 } else {
                     for (TimeGraphEntry entry : entryList) {
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphMarkerListener.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphMarkerListener.java
new file mode 100644
index 0000000..22cb98d
--- /dev/null
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/ITimeGraphMarkerListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License 2.0 which
+ * accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.widgets.timegraph;
+
+/**
+ * A listener which is notified when a timegraph hides or shows a marker
+ * category.
+ *
+ * @author Patrick Tasse
+ * @since 7.1
+ */
+public interface ITimeGraphMarkerListener {
+
+    /**
+     * Notifies that the timegraph has hidden or shown a marker category.
+     */
+    void markerCategoriesChanged();
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java
index 3e2db26..dd42509 100644
--- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java
+++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/TimeGraphViewer.java
@@ -160,6 +160,7 @@
     private List<ITimeGraphTimeListener> fTimeListeners = new ArrayList<>();
     private List<ITimeGraphRangeListener> fRangeListeners = new ArrayList<>();
     private List<ITimeGraphBookmarkListener> fBookmarkListeners = new ArrayList<>();
+    private List<ITimeGraphMarkerListener> fMarkerListeners = new ArrayList<>();
 
     // Time format, using Epoch reference, Relative time format(default),
     // Number, or Cycles
@@ -1508,10 +1509,23 @@
             updateMarkerList();
             updateMarkerActions();
             getControl().redraw();
+            fireMarkerCategoriesChanged();
         }
     }
 
     /**
+     * Returns true if the specified marker category is visible
+     *
+     * @param category
+     *            the marker category
+     * @return true if the specified marker category is visible
+     * @since 7.1
+     */
+    public boolean isMarkerCategoryVisible(String category) {
+        return !fHiddenMarkerCategories.contains(category);
+    }
+
+    /**
      * Set the markers list.
      *
      * @param markers
@@ -1538,6 +1552,34 @@
     }
 
     /**
+     * Add a marker listener
+     *
+     * @param listener
+     *            The listener to add
+     * @since 7.1
+     */
+    public void addMarkerListener(ITimeGraphMarkerListener listener) {
+        fMarkerListeners.add(listener);
+    }
+
+    /**
+     * Remove a marker listener
+     *
+     * @param listener
+     *            The listener to remove
+     * @since 7.1
+     */
+    public void removeMarkerListener(ITimeGraphMarkerListener listener) {
+        fMarkerListeners.remove(listener);
+    }
+
+    private void fireMarkerCategoriesChanged() {
+        for (ITimeGraphMarkerListener listener : fMarkerListeners) {
+            listener.markerCategoriesChanged();
+        }
+    }
+
+    /**
      * Callback to set a selected event in the view
      *
      * @param event