Bug 576225 - API for Launch Configuration View

The public API of the Launch Configuration View consists of three
interfaces.

 * ILaunchObjectProvider. This is the main interface implemented by
   extending contributions. It must be registered as a service, most
   easily using @Component annotation for declarative services.
 * ILaunchObject. This is provided the the ILaunchObjectProvider
   implementation and describes a launch-able "thing".
 * IBackgroundLaunchExecutor. This is a small helper which allows other
   extensions convenient access to the logic for launching a specific
   launch configuration as a background job.

Both interfaces have default implementations inside the view plugin
which handle "default" Eclipse launch configurations. External
extensions may provide additional logic, for an example see
https://github.com/ssi-schaefer/lcdsl

The LaunchConfigurationViewPlugin Activator is introduced to allow
access the the default implementation of the IBackgroundLaunchExecutor
which is provided by the view.

Change-Id: Iad47ec7e96fbf89709f0b46ef5aa1125d6789dea
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/185799
Tested-by: Lars Vogel <Lars.Vogel@vogella.com>
Reviewed-by: Lars Vogel <Lars.Vogel@vogella.com>
diff --git a/org.eclipse.debug.ui.launchview/META-INF/MANIFEST.MF b/org.eclipse.debug.ui.launchview/META-INF/MANIFEST.MF
index 61aaf4f..2ec5eb7 100644
--- a/org.eclipse.debug.ui.launchview/META-INF/MANIFEST.MF
+++ b/org.eclipse.debug.ui.launchview/META-INF/MANIFEST.MF
@@ -20,9 +20,5 @@
 Bundle-ActivationPolicy: lazy
 Service-Component: OSGI-INF/org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel.xml,
  OSGI-INF/org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider.xml
-Export-Package: org.eclipse.debug.ui.launchview.internal;x-internal:=true,
- org.eclipse.debug.ui.launchview.internal.impl;x-internal:=true,
- org.eclipse.debug.ui.launchview.internal.launcher;x-internal:=true,
- org.eclipse.debug.ui.launchview.internal.model;x-internal:=true,
- org.eclipse.debug.ui.launchview.internal.services;x-internal:=true,
- org.eclipse.debug.ui.launchview.internal.view;x-internal:=true
+Export-Package: org.eclipse.debug.ui.launchview;x-internal:=true,
+ org.eclipse.debug.ui.launchview.services;x-internal:=true
diff --git a/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider.xml b/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider.xml
index c95bd5a..cf17032 100644
--- a/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider.xml
+++ b/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="createService" deactivate="destroyService" name="org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider">
    <service>
-      <provide interface="org.eclipse.debug.ui.launchview.internal.services.ILaunchObjectProvider"/>
+      <provide interface="org.eclipse.debug.ui.launchview.services.ILaunchObjectProvider"/>
    </service>
    <implementation class="org.eclipse.debug.ui.launchview.internal.impl.DebugCoreProvider"/>
 </scr:component>
\ No newline at end of file
diff --git a/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel.xml b/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel.xml
index 290833c..0eb619a 100644
--- a/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel.xml
+++ b/org.eclipse.debug.ui.launchview/OSGI-INF/org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.2.0" activate="activate" deactivate="deactivate" immediate="true" name="org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel">
    <service>
-      <provide interface="org.eclipse.debug.ui.launchview.internal.services.LaunchModel"/>
+      <provide interface="org.eclipse.debug.ui.launchview.internal.model.ILaunchModel"/>
    </service>
-   <reference bind="addLaunchObjectProvider" cardinality="0..n" interface="org.eclipse.debug.ui.launchview.internal.services.ILaunchObjectProvider" name="LaunchObjectProvider" policy="dynamic" policy-option="greedy" unbind="removeLaunchObjectProvider"/>
+   <reference bind="addLaunchObjectProvider" cardinality="0..n" interface="org.eclipse.debug.ui.launchview.services.ILaunchObjectProvider" name="LaunchObjectProvider" policy="dynamic" policy-option="greedy" unbind="removeLaunchObjectProvider"/>
    <reference bind="setWorkbench" cardinality="1..1" interface="org.eclipse.ui.IWorkbench" name="Workbench" policy="static" unbind="unsetWorkbench"/>
    <implementation class="org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel"/>
 </scr:component>
\ No newline at end of file
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/IBackgroundLaunchExecutor.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/IBackgroundLaunchExecutor.java
new file mode 100644
index 0000000..f08d925
--- /dev/null
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/IBackgroundLaunchExecutor.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2021 SSI Schaefer IT Solutions GmbH and others.
+ *
+ * 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
+ *
+ * Contributors:
+ *     SSI Schaefer IT Solutions GmbH
+ *******************************************************************************/
+package org.eclipse.debug.ui.launchview;
+
+import java.io.File;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+
+/**
+ * Allows to execute a specified launch configuration in the background, i.e.
+ * non-blocking.
+ * <p>
+ * The launch configuration is started as a background job.
+ *
+ * @since 1.0.2
+ */
+public interface IBackgroundLaunchExecutor {
+
+	/**
+	 * Starts a launch configuration. The return value is only valid if wait is
+	 * <code>true</code>. Otherwise the launch is not awaited and the method
+	 * returns immediately.
+	 *
+	 * @param launchConf the launch configuration
+	 * @param mode the launch mode to use.
+	 * @param build whether to perform a build before launch
+	 * @param wait whether to wait for completion
+	 * @param logFile an optional {@link File} to write console output to. May
+	 *            be <code>null</code>.
+	 * @return process exit value if wait is <code>true</code>, always 0 if wait
+	 *         is <code>false</code>. -1 in case waiting was interrupted.
+	 */
+	int launchProcess(ILaunchConfiguration launchConf, String mode, boolean build, boolean wait, File logFile);
+
+}
\ No newline at end of file
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/LaunchConfigurationViewPlugin.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/LaunchConfigurationViewPlugin.java
new file mode 100644
index 0000000..3af0316
--- /dev/null
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/LaunchConfigurationViewPlugin.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2021 SSI Schaefer IT Solutions GmbH and others.
+ *
+ * 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
+ *
+ * Contributors:
+ *     SSI Schaefer IT Solutions GmbH
+ *******************************************************************************/
+package org.eclipse.debug.ui.launchview;
+
+import org.eclipse.debug.ui.launchview.internal.launcher.StandaloneLaunchConfigExecutor;
+
+/**
+ * Static Helper which provides access to internal implementations of externally
+ * available API.
+ *
+ * @since 1.0.2
+ */
+public class LaunchConfigurationViewPlugin {
+
+	/**
+	 * @return an {@link IBackgroundLaunchExecutor} which can be used to launch
+	 *         launch configurations as background jobs.
+	 */
+	public static IBackgroundLaunchExecutor getExecutor() {
+		return new StandaloneLaunchConfigExecutor();
+	}
+
+}
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreLaunchObject.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreLaunchObject.java
index a696ec6..de8ebd4 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreLaunchObject.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreLaunchObject.java
@@ -31,10 +31,10 @@
 import org.eclipse.debug.ui.DebugUITools;
 import org.eclipse.debug.ui.IDebugUIConstants;
 import org.eclipse.debug.ui.ILaunchGroup;
+import org.eclipse.debug.ui.launchview.LaunchConfigurationViewPlugin;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewBundleInfo;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewMessages;
-import org.eclipse.debug.ui.launchview.internal.launcher.StandaloneLaunchConfigExecutor;
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObject;
+import org.eclipse.debug.ui.launchview.services.ILaunchObject;
 import org.eclipse.jface.viewers.StyledString;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.ui.PlatformUI;
@@ -69,7 +69,7 @@
 
 	@Override
 	public void launch(ILaunchMode mode) {
-		StandaloneLaunchConfigExecutor.launchProcess(config, mode.getIdentifier(), true, false, null);
+		LaunchConfigurationViewPlugin.getExecutor().launchProcess(config, mode.getIdentifier(), true, false, null);
 	}
 
 	@Override
@@ -117,13 +117,13 @@
 		String launchMode = launch.getLaunchMode();
 		try {
 			launch.terminate();
-			StandaloneLaunchConfigExecutor.launchProcess(config, launchMode, true, false, null);
+			LaunchConfigurationViewPlugin.getExecutor().launchProcess(config, launchMode, true, false, null);
 		} catch (Exception e) {
 			throw new RuntimeException(NLS.bind(LaunchViewMessages.DebugCoreLaunchObject_CannotRelaunch, config.getName()), e);
 		}
 	}
 
-	public static ILaunch findLaunch(String name) {
+	private static ILaunch findLaunch(String name) {
 		for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) {
 			if (l.getLaunchConfiguration() == null || l.isTerminated()) {
 				continue;
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreProvider.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreProvider.java
index 4b025e6..44f9180 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreProvider.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/impl/DebugCoreProvider.java
@@ -30,9 +30,9 @@
 import org.eclipse.debug.core.ILaunchesListener2;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewBundleInfo;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewMessages;
-import org.eclipse.debug.ui.launchview.internal.services.AbstractLaunchObjectProvider;
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObject;
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObjectProvider;
+import org.eclipse.debug.ui.launchview.services.AbstractLaunchObjectProvider;
+import org.eclipse.debug.ui.launchview.services.ILaunchObject;
+import org.eclipse.debug.ui.launchview.services.ILaunchObjectProvider;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/launcher/StandaloneLaunchConfigExecutor.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/launcher/StandaloneLaunchConfigExecutor.java
index ac4700d..4f76c74 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/launcher/StandaloneLaunchConfigExecutor.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/launcher/StandaloneLaunchConfigExecutor.java
@@ -27,6 +27,7 @@
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.ui.launchview.IBackgroundLaunchExecutor;
 import org.eclipse.debug.ui.launchview.internal.FileLogger;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewMessages;
 import org.eclipse.debug.ui.launchview.internal.SpecificLaunchListener;
@@ -36,7 +37,7 @@
 /**
  * Wraps launching a certain ILaunchConfiguration into a job
  */
-public class StandaloneLaunchConfigExecutor {
+public class StandaloneLaunchConfigExecutor implements IBackgroundLaunchExecutor {
 
 	/**
 	 * Starts a launch configuration. The return value is only valid if wait is
@@ -51,7 +52,8 @@
 	 * @return process exit value if wait is <code>true</code>, always 0 if wait
 	 *         is <code>false</code>. -1 in case waiting was interrupted.
 	 */
-	public static int launchProcess(ILaunchConfiguration launchConf, String mode, boolean build, boolean wait, File logFile) {
+	@Override
+	public int launchProcess(ILaunchConfiguration launchConf, String mode, boolean build, boolean wait, File logFile) {
 		StandaloneLauncherJob launch = new StandaloneLauncherJob(launchConf, mode, build, wait, logFile);
 
 		launch.setPriority(Job.SHORT);
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/LaunchModel.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/ILaunchModel.java
similarity index 82%
rename from org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/LaunchModel.java
rename to org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/ILaunchModel.java
index 89d979a..3acfa28 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/LaunchModel.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/ILaunchModel.java
@@ -11,14 +11,12 @@
  * Contributors:
  *     SSI Schaefer IT Solutions GmbH
  *******************************************************************************/
-package org.eclipse.debug.ui.launchview.internal.services;
-
-import org.eclipse.debug.ui.launchview.internal.model.LaunchObjectContainerModel;
+package org.eclipse.debug.ui.launchview.internal.model;
 
 /**
  * Service which controls the lifecycle of the model which the view is based on.
  */
-public interface LaunchModel {
+public interface ILaunchModel {
 
 	/**
 	 * @return the current model. Never <code>null</code>. Always created from
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchObjectModel.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchObjectModel.java
index 80bf5d2..298f5c3 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchObjectModel.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchObjectModel.java
@@ -13,7 +13,7 @@
  *******************************************************************************/
 package org.eclipse.debug.ui.launchview.internal.model;
 
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObject;
+import org.eclipse.debug.ui.launchview.services.ILaunchObject;
 import org.eclipse.jface.viewers.StyledString;
 import org.eclipse.swt.graphics.Image;
 
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchViewModel.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchViewModel.java
index 4f2fb92..a017d99 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchViewModel.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/model/LaunchViewModel.java
@@ -19,8 +19,7 @@
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObjectProvider;
-import org.eclipse.debug.ui.launchview.internal.services.LaunchModel;
+import org.eclipse.debug.ui.launchview.services.ILaunchObjectProvider;
 import org.eclipse.ui.IWorkbench;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -31,7 +30,7 @@
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component(immediate = true)
-public class LaunchViewModel implements LaunchModel {
+public class LaunchViewModel implements ILaunchModel {
 
 	public Set<ILaunchObjectProvider> providers = new TreeSet<>((a, b) -> {
 		int x = Integer.compare(b.getPriority(), a.getPriority());
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchAction.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchAction.java
index 71b24f3..df876f7 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchAction.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchAction.java
@@ -23,7 +23,7 @@
 import org.eclipse.debug.core.ILaunchMode;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewBundleInfo;
 import org.eclipse.debug.ui.launchview.internal.LaunchViewMessages;
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObject;
+import org.eclipse.debug.ui.launchview.services.ILaunchObject;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.menu.MDirectMenuItem;
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchViewImpl.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchViewImpl.java
index 6cc629b..3a76ffb 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchViewImpl.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/view/LaunchViewImpl.java
@@ -38,7 +38,7 @@
 import org.eclipse.debug.ui.launchview.internal.model.LaunchObjectFavoriteContainerModel;
 import org.eclipse.debug.ui.launchview.internal.model.LaunchObjectModel;
 import org.eclipse.debug.ui.launchview.internal.model.LaunchViewModel;
-import org.eclipse.debug.ui.launchview.internal.services.ILaunchObject;
+import org.eclipse.debug.ui.launchview.services.ILaunchObject;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/AbstractLaunchObjectProvider.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/AbstractLaunchObjectProvider.java
similarity index 94%
rename from org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/AbstractLaunchObjectProvider.java
rename to org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/AbstractLaunchObjectProvider.java
index af1e6c3..c8de59c 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/AbstractLaunchObjectProvider.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/AbstractLaunchObjectProvider.java
@@ -11,7 +11,7 @@
  * Contributors:
  *     SSI Schaefer IT Solutions GmbH
  *******************************************************************************/
-package org.eclipse.debug.ui.launchview.internal.services;
+package org.eclipse.debug.ui.launchview.services;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -19,6 +19,8 @@
 /**
  * Base class for {@link ILaunchObjectProvider} implementations which require
  * listeners to be notified on updates.
+ *
+ * @since 1.0.2
  */
 public abstract class AbstractLaunchObjectProvider implements ILaunchObjectProvider {
 
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObject.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObject.java
similarity index 91%
rename from org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObject.java
rename to org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObject.java
index 279323f..7dc8153 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObject.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObject.java
@@ -11,7 +11,7 @@
  * Contributors:
  *     SSI Schaefer IT Solutions GmbH
  *******************************************************************************/
-package org.eclipse.debug.ui.launchview.internal.services;
+package org.eclipse.debug.ui.launchview.services;
 
 import org.eclipse.debug.core.ILaunchConfigurationType;
 import org.eclipse.debug.core.ILaunchMode;
@@ -21,6 +21,11 @@
 
 /**
  * A {@link ILaunchObject} describes a single launch-able "thing".
+ * <p>
+ * Instances of this interface are provided by extensions by a custom
+ * {@link ILaunchObjectProvider} implementation in the extension.
+ *
+ * @since 1.0.2
  */
 public interface ILaunchObject extends Comparable<ILaunchObject> {
 
diff --git a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObjectProvider.java b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObjectProvider.java
similarity index 85%
rename from org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObjectProvider.java
rename to org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObjectProvider.java
index 70e78ff..653f424 100644
--- a/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/internal/services/ILaunchObjectProvider.java
+++ b/org.eclipse.debug.ui.launchview/src/org/eclipse/debug/ui/launchview/services/ILaunchObjectProvider.java
@@ -11,7 +11,7 @@
  * Contributors:
  *     SSI Schaefer IT Solutions GmbH
  *******************************************************************************/
-package org.eclipse.debug.ui.launchview.internal.services;
+package org.eclipse.debug.ui.launchview.services;
 
 import java.util.Set;
 import java.util.function.Supplier;
@@ -20,9 +20,14 @@
 import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
 
 /**
- * Provides different {@link ILaunchObject} implementations to the view for
- * display. Also allows some interaction with the view by means of an update
- * listener and menu contributions.
+ * Provides different {@link ILaunchObject} instances to the view for display.
+ * Also allows some interaction with the view by means of an update listener and
+ * menu contributions.
+ * <p>
+ * Contribute extensions to the view by implementing this interface and
+ * registering it as a {@literal @Component} (declarative service).
+ *
+ * @since 1.0.2
  */
 public interface ILaunchObjectProvider {