diff --git a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/AddonSuggestionFinderService.java b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/AddonSuggestionFinderService.java index 24e5a23d537..47c269f6aee 100644 --- a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/AddonSuggestionFinderService.java +++ b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/AddonSuggestionFinderService.java @@ -87,6 +87,17 @@ public void close() throws Exception { addonInfoProviders.clear(); } + /** + * The OH framework calls this method to enable/disable the finder with the given service id (if any). + * + * @param finderServiceId the service id of the finder to be enabled/disabled. + * @param enable true to enable, false to disable + */ + public void enable(String finderServiceId, boolean enable) { + addonSuggestionFinders.stream().filter(f -> finderServiceId.equals(f.getServiceType())).findFirst() + .ifPresent(f -> f.enable(enable)); + } + public Set getSuggestedAddons(@Nullable Locale locale) { return addonSuggestionFinders.stream().map(f -> f.getSuggestedAddons()).flatMap(Collection::stream) .collect(Collectors.toSet()); diff --git a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/AddonSuggestionFinder.java b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/AddonSuggestionFinder.java index 2e8809ce3e7..0f8c5afca94 100644 --- a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/AddonSuggestionFinder.java +++ b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/AddonSuggestionFinder.java @@ -27,13 +27,34 @@ public interface AddonSuggestionFinder { /** - * The framework calls this method to scan through the candidate list of {@link AddonInfo} and return a subset of + * This method should be overridden and referenced so that the OSGI framework will call it when the component is + * deactivated. It should clear the finder's internal state. + */ + public void deactivate(); + + /** + * The OH framework calls this method to enable or disable the finder. Typically e.g. for upnp and mdns, it connects + * to resp. disconnects from, the underlying discovery transport. + * + * @param enable true to enable, false to disable + */ + public void enable(boolean enable); + + /** + * The OH framework calls this method to read the finder service type. + * + * @return the finder service type + */ + public String getServiceType(); + + /** + * The OH framework calls this method to scan through the candidate list of {@link AddonInfo} and return a subset of * those that it suggests to be installed. */ public Set getSuggestedAddons(); /** - * The framework calls this method to provide a list of {@link AddonInfo} elements which contain potential + * The OH framework calls this method to provide a list of {@link AddonInfo} elements which contain potential * candidates that this finder can iterate over in order to detect which ones to return via the * {@code getSuggestedAddons()} method. * diff --git a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/BaseAddonSuggestionFinder.java b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/BaseAddonSuggestionFinder.java index b17d459321d..8e3f50c7723 100644 --- a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/BaseAddonSuggestionFinder.java +++ b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/BaseAddonSuggestionFinder.java @@ -16,7 +16,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.regex.Pattern; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -51,18 +50,13 @@ protected static boolean propertyMatches(Map propertyPatternMap protected final List addonCandidates = Collections.synchronizedList(new ArrayList<>()); - protected void deactivate() { - resetAddonCandidates(); - } - - public abstract Set getSuggestedAddons(); - - protected void resetAddonCandidates() { + @Override + public void deactivate() { addonCandidates.clear(); } - public void setAddonCandidates(List candidates) { - resetAddonCandidates(); + public synchronized void setAddonCandidates(List candidates) { + addonCandidates.clear(); addonCandidates.addAll(candidates); } } diff --git a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/MDNSAddonSuggestionFinder.java b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/MDNSAddonSuggestionFinder.java index 6905084c604..21bf4c21176 100644 --- a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/MDNSAddonSuggestionFinder.java +++ b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/MDNSAddonSuggestionFinder.java @@ -71,13 +71,43 @@ public void addService(ServiceInfo service, boolean isResolved) { } } + private void connect() { + addonCandidates + .forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType())) + .filter(m -> !m.getMdnsServiceType().isEmpty()).forEach(m -> { + String serviceType = m.getMdnsServiceType(); + mdnsClient.addServiceListener(serviceType, this); + scheduler.submit(() -> mdnsClient.list(serviceType)); + })); + } + @Deactivate @Override - protected void deactivate() { + public void deactivate() { services.clear(); + disconnect(); super.deactivate(); } + private void disconnect() { + addonCandidates.forEach(c -> c.getDiscoveryMethods().stream() + .filter(m -> SERVICE_TYPE.equals(m.getServiceType())).filter(m -> !m.getMdnsServiceType().isEmpty()) + .forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this))); + } + + @Override + public void enable(boolean enable) { + disconnect(); + if (enable) { + connect(); + } + } + + @Override + public String getServiceType() { + return SERVICE_TYPE; + } + @Override public Set getSuggestedAddons() { Set result = new HashSet<>(); @@ -110,6 +140,10 @@ && propertyMatches(matchProperties, APPLICATION, service.getApplication()) return result; } + /* + * ************ MDNSClient call-back methods ************ + */ + @Override public void serviceAdded(@Nullable ServiceEvent event) { if (event != null) { @@ -134,22 +168,10 @@ public void serviceResolved(@Nullable ServiceEvent event) { } } - @Override - protected void resetAddonCandidates() { - addonCandidates.forEach(c -> c.getDiscoveryMethods().stream() - .filter(m -> SERVICE_TYPE.equals(m.getServiceType())).filter(m -> !m.getMdnsServiceType().isEmpty()) - .forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this))); - super.resetAddonCandidates(); - } - @Override public void setAddonCandidates(List candidates) { + disconnect(); super.setAddonCandidates(candidates); - candidates.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType())) - .filter(m -> !m.getMdnsServiceType().isEmpty()).forEach(m -> { - String serviceType = m.getMdnsServiceType(); - mdnsClient.addServiceListener(serviceType, this); - scheduler.submit(() -> mdnsClient.list(serviceType)); - })); + connect(); } } diff --git a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/UpnpAddonSuggestionFinder.java b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/UpnpAddonSuggestionFinder.java index fe9c7c712e1..a38885a695e 100644 --- a/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/UpnpAddonSuggestionFinder.java +++ b/bundles/org.openhab.core.config.discovery.addon/src/main/java/org/openhab/core/config/discovery/addon/finders/UpnpAddonSuggestionFinder.java @@ -74,11 +74,7 @@ public class UpnpAddonSuggestionFinder extends BaseAddonSuggestionFinder impleme @Activate public UpnpAddonSuggestionFinder(@Reference UpnpService upnpService) { this.upnpService = upnpService; - Registry registry = upnpService.getRegistry(); - for (RemoteDevice device : registry.getRemoteDevices()) { - remoteDeviceAdded(registry, device); - } - registry.addListener(this); + connect(); } public void addDevice(RemoteDevice device) { @@ -93,14 +89,39 @@ public void addDevice(RemoteDevice device) { } } + private void connect() { + Registry registry = upnpService.getRegistry(); + for (RemoteDevice device : registry.getRemoteDevices()) { + remoteDeviceAdded(registry, device); + } + registry.addListener(this); + } + @Deactivate @Override - protected void deactivate() { + public void deactivate() { devices.clear(); - upnpService.getRegistry().removeListener(this); + disconnect(); super.deactivate(); } + private void disconnect() { + upnpService.getRegistry().removeListener(this); + } + + @Override + public void enable(boolean enable) { + disconnect(); + if (enable) { + connect(); + } + } + + @Override + public String getServiceType() { + return SERVICE_TYPE; + } + @Override public Set getSuggestedAddons() { Set result = new HashSet<>(); @@ -179,6 +200,10 @@ && propertyMatches(matchProperties, FRIENDLY_NAME, friendlyName)) { return result; } + /* + * ************ UpnpService call-back methods ************ + */ + @Override public void afterShutdown() { }