Add connection status reconciliation + fixes + tweaks
authordadubrow
Wed, 06 Jan 2010 13:32:23 -0600
changeset 748 7bd40a2d0a18
parent 747 11dc6d4e9da5
child 749 22f0d10fce10
Add connection status reconciliation + fixes + tweaks
connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusInUseDisconnected.png
connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusNotReady.png
connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusReady.png
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/interfaces/AbstractConnection.java
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/api/IConnection2.java
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/registry/Registry.java
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/ui/ConnectionStatusSelectorContribution.java
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/messages.properties
connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/view/ConnectionsView.java
debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/Activator.java
debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/service/TRKConnectedService.java
debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/status/ConnectionStatusReconciler.java
Binary file connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusInUseDisconnected.png has changed
Binary file connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusNotReady.png has changed
Binary file connectivity/com.nokia.carbide.remoteConnections/icons/connectionStatusReady.png has changed
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/interfaces/AbstractConnection.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/interfaces/AbstractConnection.java	Wed Jan 06 13:32:23 2010 -0600
@@ -35,27 +35,34 @@
 	
 	public static class ConnectionStatus implements IConnectionStatus {
 		private EConnectionStatus estatus;
-		private String description;
+		private String shortDescription;
+		private String longDescription;
 		
-		public ConnectionStatus(EConnectionStatus estatus, String description) {
+		public ConnectionStatus(EConnectionStatus estatus, String shortDescription, String longDescription) {
 			this.estatus = estatus;
-			this.description = description;
+			this.shortDescription = shortDescription;
+			this.longDescription = longDescription;
 		}
 
 		public EConnectionStatus getEConnectionStatus() {
 			return estatus;
 		}
 		
-		public String getDescription() {
-			return description;
+		public String getShortDescription() {
+			return shortDescription;
 		}
 
+		public String getLongDescription() {
+			return longDescription;
+		}
+		
 		public void setEStatus(EConnectionStatus estatus) {
 			this.estatus = estatus;
 		}
 
-		public void setDescription(String description) {
-			this.description = description;
+		public void setDescriptions(String shortDescription, String longDescription) {
+			this.shortDescription = shortDescription;
+			this.longDescription = longDescription;
 		}
 	}
 
@@ -71,7 +78,7 @@
 	public AbstractConnection(IConnectionType connectionType, Map<String, String> settings) {
 		this.connectionType = connectionType;
 		this.settings = new HashMap<String, String>(settings);
-		status = new ConnectionStatus(EConnectionStatus.NOT_READY, ""); //$NON-NLS-1$
+		status = new ConnectionStatus(EConnectionStatus.NONE, "", ""); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 
 	public void dispose() {
@@ -121,6 +128,7 @@
 	public void setStatus(IConnectionStatus status) {
 		Check.checkArg(status);
 		this.status = status;
+		fireStatusChanged();
 	}
 	
 	public void addStatusChangedListener(IConnectionStatusChangedListener listener) {
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/api/IConnection2.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/api/IConnection2.java	Wed Jan 06 13:32:23 2010 -0600
@@ -46,12 +46,14 @@
 	 */
 	public interface IConnectionStatus {
 		enum EConnectionStatus {
-			READY, NOT_READY, IN_USE, IN_USE_DISCONNECTED
+			READY, NOT_READY, IN_USE, IN_USE_DISCONNECTED, NONE
 		};
 		
 		EConnectionStatus getEConnectionStatus();
 		
-		String getDescription();
+		String getShortDescription();
+		
+		String getLongDescription();
 	}
 	
 	/**
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/registry/Registry.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/registry/Registry.java	Wed Jan 06 13:32:23 2010 -0600
@@ -562,7 +562,8 @@
 		// 	when not in-use, remove and stop waiting
 		if (connection.getStatus().getEConnectionStatus().equals(EConnectionStatus.IN_USE)) {
 			IConnectionStatus status = new ConnectionStatus(EConnectionStatus.IN_USE_DISCONNECTED, 
-						"connection has been disconnected while in use, please reconnect");
+					Messages.getString("ConnectionsView.DisconnectedLabel"), //$NON-NLS-1$
+					Messages.getString("ConnectionsView.DisconnectedDesc")); //$NON-NLS-1$
 			connection.setStatus(status);
 			IConnectionStatusChangedListener listener = new IConnectionStatusChangedListener() {
 				public void statusChanged(IConnectionStatus status) {
@@ -601,10 +602,11 @@
 			IConnectionStatus status;
 			if (ConnectionUIUtils.isSomeServiceInUse(connection)) {
 				status = new ConnectionStatus(EConnectionStatus.IN_USE, 
+						Messages.getString("ConnectionsView.InUseLabel"), //$NON-NLS-1$
 						Messages.getString("ConnectionsView.InUseDesc")); //$NON-NLS-1$
 			}
 			else {
-				status = new ConnectionStatus(EConnectionStatus.NOT_READY, ""); //$NON-NLS-1$
+				status = new ConnectionStatus(EConnectionStatus.NOT_READY, "", ""); //$NON-NLS-1$ //$NON-NLS-2$
 			}
 			connection.setStatus(status);
 			return true;
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/ui/ConnectionStatusSelectorContribution.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/internal/ui/ConnectionStatusSelectorContribution.java	Wed Jan 06 13:32:23 2010 -0600
@@ -52,11 +52,8 @@
 
 import com.nokia.carbide.remoteconnections.Messages;
 import com.nokia.carbide.remoteconnections.RemoteConnectionsActivator;
-import com.nokia.carbide.remoteconnections.interfaces.IConnectedService;
 import com.nokia.carbide.remoteconnections.interfaces.IConnection;
 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager;
-import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus;
-import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatusChangedListener;
 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener;
 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionsManagerListener;
 import com.nokia.carbide.remoteconnections.internal.api.IConnection2;
@@ -97,7 +94,7 @@
 	/**
 	 * Contains all the listeners.  In most cases we just recreate the contribution status item.
 	 */
-	class ListenerBlock implements IConnectionListener, IConnectionsManagerListener, IStatusChangedListener, IConnectionStatusChangedListener {
+	class ListenerBlock implements IConnectionListener, IConnectionsManagerListener, IConnectionStatusChangedListener {
 
 		/* (non-Javadoc)
 		 * @see com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener#connectionAdded(com.nokia.carbide.remoteconnections.interfaces.IConnection)
@@ -145,13 +142,6 @@
 		}
 
 		/* (non-Javadoc)
-		 * @see com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatusChangedListener#statusChanged(com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus)
-		 */
-		public void statusChanged(IStatus status) {
-			updateConnectionStatus(null);
-		}
-
-		/* (non-Javadoc)
 		 * @see com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatusChangedListener#statusChanged(com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatus)
 		 */
 		public void statusChanged(IConnectionStatus status) {
@@ -320,7 +310,8 @@
 				createConnectionMenuItem(menu, connection, defaultConnection, number++);
 			}
 			
-			new MenuItem(menu, SWT.SEPARATOR);
+			if (!staticConnections.isEmpty())
+				new MenuItem(menu, SWT.SEPARATOR);
 			
 			for (IConnection connection : staticConnections) {
 				createConnectionMenuItem(menu, connection, defaultConnection, number++);
@@ -375,9 +366,6 @@
 			if (defaultConnection instanceof IConnection2) {
 				((IConnection2) defaultConnection).addStatusChangedListener(listenerBlock);
 			}
-			for (IConnectedService service : manager.getConnectedServices(defaultConnection)) {
-				service.addStatusChangedListener(listenerBlock);
-			}
 		}
 	}
 
@@ -386,9 +374,6 @@
 			if (defaultConnection instanceof IConnection2) {
 				((IConnection2) defaultConnection).removeStatusChangedListener(listenerBlock);
 			}
-			for (IConnectedService service : manager.getConnectedServices(defaultConnection)) {
-				service.removeStatusChangedListener(listenerBlock);
-			}
 		}
 		manager.removeConnectionListener(listenerBlock);
 		Registry.instance().removeConnectionStoreChangedListener(listenerBlock);
@@ -435,7 +420,7 @@
 		
 		String statusString = null;
 		if (status != null) {
-			statusString = status.getDescription();
+			statusString = createStatusString(status);
 		}
 		
 		if (TextUtils.isEmpty(statusString)) {
@@ -449,6 +434,16 @@
 		return MessageFormat.format(Messages.getString("ConnectionStatusSelectorContribution.ConnectionStatusFormat"), defaultConnection.getDisplayName(), statusString); //$NON-NLS-1$
 	}
 
+	private String createStatusString(IConnectionStatus status) {
+		String shortDescription = status.getShortDescription();
+		if (shortDescription == null || shortDescription.length() == 0)
+			return ""; //$NON-NLS-1$
+		String pattern = Messages.getString("ConnectionStatusSelectorContribution.StatusFormat"); //$NON-NLS-1$
+		if (shortDescription != null)
+			shortDescription = shortDescription.toLowerCase();
+		return MessageFormat.format(pattern, shortDescription, status.getLongDescription());
+	}
+
 	/**
 	 * Get the image representing the connection status.
 	 * @param connection
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/messages.properties	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/messages.properties	Wed Jan 06 13:32:23 2010 -0600
@@ -61,7 +61,10 @@
 ConnectionsView.EnableTestActionLabel=Enable Service Testing
 ConnectionsView.DisableTestActionLabel=Disable Service Testing
 ConnectionsView.TypeColumnHeader=Type
+ConnectionsView.InUseLabel=In use
 ConnectionsView.InUseDesc=At least one service is using this connection
+ConnectionsView.DisconnectedLabel=Disconnected
+ConnectionsView.DisconnectedDesc=Connection has been disconnected while in use, please reconnect
 ConnectionTypePage.ConnectionNameInUseError=The connection name ''{0}'' is in use
 ConnectionTypePage.Description=Select a name and the connection type for the connection
 ConnectionTypePage.NameLabel=Connection name:
@@ -77,6 +80,7 @@
 ConnectionStatusSelectorContribution.NoConnectionsDefinedOrDetected=No connections defined or detected
 ConnectionStatusSelectorContribution.NoDynamicOrManualConnectionsTooltip=No default connection selected.
 ConnectionStatusSelectorContribution.NotInUse=Not in use
+ConnectionStatusSelectorContribution.StatusFormat=Connection is {0}: {1}
 ExportPage.BrowseGroupLabel=Connections file:
 ExportPage.Description=Select connections to export
 ExportPage.FileDialogTitle=Save As
--- a/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/view/ConnectionsView.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/remoteconnections/view/ConnectionsView.java	Wed Jan 06 13:32:23 2010 -0600
@@ -85,6 +85,7 @@
 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener;
 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionsManagerListener;
 import com.nokia.carbide.remoteconnections.internal.api.IConnection2;
+import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatus;
 import com.nokia.carbide.remoteconnections.internal.registry.Registry;
 import com.nokia.carbide.remoteconnections.internal.ui.ConnectionUIUtils;
 import com.nokia.carbide.remoteconnections.settings.ui.SettingsWizard;
@@ -259,9 +260,16 @@
 				}
 			}
 			else if (value instanceof IConnection) {
-				IStatus status = ConnectionUIUtils.getFirstInUseServiceStatus((IConnection) value);
-				if (status != null)
-					return status.getShortDescription();
+				if (isDynamicConnection(value)) {
+					IConnectionStatus status = ((IConnection2) value).getStatus();
+					if (status != null)
+						return status.getShortDescription();
+				}
+				else {	
+					IStatus status = ConnectionUIUtils.getFirstInUseServiceStatus((IConnection) value);
+					if (status != null)
+						return status.getShortDescription();
+				}
 			}
 				
 			return null;
@@ -316,7 +324,12 @@
 				}
 			}
 			else if (value instanceof IConnection) {
-				if (ConnectionUIUtils.isSomeServiceInUse((IConnection) value)) {
+				if (isDynamicConnection(value)) {
+					IConnectionStatus status = ((IConnection2) value).getStatus();
+					if (status != null)
+						return status.getLongDescription();
+				}
+				else if (ConnectionUIUtils.isSomeServiceInUse((IConnection) value)) {
 					return Messages.getString("ConnectionsView.InUseDesc");
 				}
 			}
@@ -707,7 +720,7 @@
 			@Override
 			public void run() {
 				ISelection selection = viewer.getSelection();
-				if (selection.isEmpty())
+				if (selection.isEmpty() || !canBeEdited(selection))
 					return;
 				TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
 				Object value = node.getValue();
@@ -776,6 +789,7 @@
 			@Override
 			public void run() {
 				Registry.instance().setDefaultConnection(getSelectedConnection());
+				setEnabled(false);
 			}
 		};
 		action.setId(SET_DEFAULT_ACTION);
@@ -868,12 +882,16 @@
 		return null;
 	}
 
-	private boolean isDynamicConnection(Object object) {
+	private static boolean isDynamicConnection(Object object) {
 		return object instanceof IConnection2 && ((IConnection2) object).isDynamic();
 	}
 
 	private boolean selectionCanBeEdited() {
 		ISelection selection = viewer.getSelection();
+		return canBeEdited(selection);
+	}
+
+	private static boolean canBeEdited(ISelection selection) {
 		if (selection.isEmpty())
 			return false;
 		TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
--- a/debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/Activator.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/Activator.java	Wed Jan 06 13:32:23 2010 -0600
@@ -18,23 +18,16 @@
 
 package com.nokia.carbide.trk.support;
 
-import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerConsts;
-import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerPlugin;
-import com.nokia.cpp.internal.api.utils.core.Logging;
-
-import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
-public class Activator extends AbstractUIPlugin {
+import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerConsts;
+import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerPlugin;
+import com.nokia.carbide.trk.support.status.ConnectionStatusReconciler;
+import com.nokia.cpp.internal.api.utils.core.Logging;
 
-	private static final String INTERNAL_ONLY_FEATURE = "Carbide_InternalOnly"; //$NON-NLS-1$
-	private static final String INTERNAL_ONLY_DESC = "Internal Only Feature"; //$NON-NLS-1$
-	private static final String INTERNAL_ONLY_VERSION = "2.0"; //$NON-NLS-1$
-	private static final String TRACE_FEATURE = "Carbide_OST_Trace"; //$NON-NLS-1$
-	private static final String TRACE_DESC = "Carbide Trace Feature"; //$NON-NLS-1$
-	private static final String TRACE_VERSION = "2.0"; //$NON-NLS-1$
+public class Activator extends AbstractUIPlugin {
 
 	// The plug-in ID
 	public static final String PLUGIN_ID = "com.nokia.carbide.trk.support"; //$NON-NLS-1$
@@ -55,6 +48,7 @@
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
 		plugin = this;
+		ConnectionStatusReconciler.getInstance();
 	}
 
 	/*
@@ -62,6 +56,7 @@
 	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
 	 */
 	public void stop(BundleContext context) throws Exception {
+		ConnectionStatusReconciler.getInstance().dispose();
 		plugin = null;
 		super.stop(context);
 	}
--- a/debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/service/TRKConnectedService.java	Wed Jan 06 08:02:47 2010 -0600
+++ b/debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/service/TRKConnectedService.java	Wed Jan 06 13:32:23 2010 -0600
@@ -40,6 +40,8 @@
  */
 public class TRKConnectedService extends AbstractConnectedService {
 	
+	public static final String PROP_SYS_TRK = "is-system-trk"; //$NON-NLS-1$
+	
 	static {
 		try {
 			System.loadLibrary("GetTRKVersion"); //$NON-NLS-1$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debuggercdi/com.nokia.carbide.trk.support/src/com/nokia/carbide/trk/support/status/ConnectionStatusReconciler.java	Wed Jan 06 13:32:23 2010 -0600
@@ -0,0 +1,218 @@
+/**
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+package com.nokia.carbide.trk.support.status;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.nokia.carbide.remoteconnections.RemoteConnectionsActivator;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectedService;
+import com.nokia.carbide.remoteconnections.interfaces.IConnection;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager;
+import com.nokia.carbide.remoteconnections.interfaces.AbstractConnection.ConnectionStatus;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatusChangedListener;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus.EStatus;
+import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener;
+import com.nokia.carbide.remoteconnections.internal.api.IConnection2;
+import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatus.EConnectionStatus;
+import com.nokia.carbide.trk.support.connection.USBConnectionType;
+import com.nokia.carbide.trk.support.service.TRKConnectedService;
+import com.nokia.carbide.trk.support.service.TracingConnectedService;
+
+/**
+ * A singleton object that manages the device status of dynamic connections
+ * based on the status of the TRK and Tracing services.
+ */
+public class ConnectionStatusReconciler {
+	
+	private class ConnectionListener implements IConnectionListener {
+
+		@Override
+		public void connectionAdded(IConnection connection) {
+			addConnection(connection);
+		}
+
+		@Override
+		public void connectionRemoved(IConnection connection) {
+			removeConnection(connection);
+		}
+		
+		@Override
+		public void defaultConnectionSet(IConnection connection) {}
+		
+	}
+	
+	private class ServiceStatusListener implements IStatusChangedListener {
+
+		@Override
+		public void statusChanged(IStatus status) {
+			handleServiceStatusChange(status);
+		}
+		
+	}
+	
+	private static ConnectionStatusReconciler instance;
+	private IConnectionsManager manager;
+	private IConnectionListener connectionListener;
+	private List<IConnection2> handledConnections;
+	private ServiceStatusListener serviceStatusListener;
+	
+	private ConnectionStatusReconciler() {
+		connectionListener = new ConnectionListener();
+		manager = RemoteConnectionsActivator.getConnectionsManager();
+		manager.addConnectionListener(connectionListener);
+		handledConnections = new ArrayList<IConnection2>();
+		serviceStatusListener = new ServiceStatusListener();
+	}
+	
+	public static ConnectionStatusReconciler getInstance() {
+		if (instance == null)
+			instance = new ConnectionStatusReconciler();
+		
+		return instance;
+	}
+
+	public void dispose() {
+		manager.removeConnectionListener(connectionListener);
+		for (IConnection2 connection : new ArrayList<IConnection2>(handledConnections)) {
+			removeConnection(connection);
+		}
+	}
+
+	private boolean handlesConnection(IConnection connection) {
+		// only manage status for USBConnectionTypes for now
+		// in future other IConnection2 types may also be managed
+		return connection.getConnectionType() instanceof USBConnectionType;
+	}
+
+	private boolean isSysTRK(TRKConnectedService service) {
+		String value = service.getProperties().get(TRKConnectedService.PROP_SYS_TRK);
+		return value != null && Boolean.getBoolean(value);
+	}
+	
+	private void addConnection(IConnection connection) {
+		if (!handlesConnection(connection))
+			return;
+		
+		handledConnections.add((IConnection2) connection);
+		for (IConnectedService service : manager.getConnectedServices(connection)) {
+			if (service instanceof TRKConnectedService ||
+					service instanceof TracingConnectedService) {
+				service.addStatusChangedListener(serviceStatusListener);
+			}
+		}
+		reconcileConnection((IConnection2) connection);
+	}
+	
+	private void reconcileConnection(IConnection2 connection) {
+		boolean isSysTRK = false;
+		EStatus trkStatus = EStatus.UNKNOWN;
+		EStatus traceStatus = EStatus.UNKNOWN;
+		for (IConnectedService service : manager.getConnectedServices(connection)) {
+			if (service instanceof TRKConnectedService) {
+				isSysTRK = isSysTRK((TRKConnectedService) service);
+				trkStatus = service.getStatus().getEStatus();
+			}
+			if (service instanceof TracingConnectedService) {
+				traceStatus = service.getStatus().getEStatus();
+			}
+		}
+		setConnectionStatus((IConnection2) connection, isSysTRK, trkStatus, traceStatus);
+	}
+
+	private void setConnectionStatus(IConnection2 connection, boolean isSysTRK, EStatus trkStatus, EStatus traceStatus) {
+		// use trk status
+		EConnectionStatus connectionStatus = service2ConnectionStatus(trkStatus);
+		// if sys trk, tracing also used
+		if (isSysTRK && connectionStatus.equals(EConnectionStatus.READY)) {
+			connectionStatus = service2ConnectionStatus(traceStatus);
+		}
+
+		String shortDesc = getShortDescriptionForStatus(connectionStatus);
+		StringBuilder longDesc = new StringBuilder("TRK service ");
+		longDesc.append(getServiceStatusString(trkStatus));
+		if (isSysTRK) {
+			longDesc.append(", Tracing service ");
+			longDesc.append(getServiceStatusString(traceStatus));
+		}
+		
+		connection.setStatus(new ConnectionStatus(connectionStatus, shortDesc, longDesc.toString()));
+	}
+
+	private String getShortDescriptionForStatus(EConnectionStatus connectionStatus) {
+		switch (connectionStatus) {
+			case READY:
+				return "Ready";
+			case NOT_READY:
+				return "Not Ready";
+			case IN_USE:
+				return "In Use";
+			case IN_USE_DISCONNECTED:
+				return "Disconnected";
+			}
+		return "";
+	}
+
+	private String getServiceStatusString(EStatus status) {
+		switch (status) {
+			case UP:
+				return "available";
+			case DOWN:
+				return "unavailable";
+			case IN_USE:
+				return "in use";
+		}
+		return "";
+	}
+
+	private EConnectionStatus service2ConnectionStatus(EStatus serviceStatus) {
+		switch (serviceStatus) {
+			case UP:
+				return EConnectionStatus.READY;
+			case DOWN:
+				return EConnectionStatus.NOT_READY;
+			case IN_USE:
+				return EConnectionStatus.IN_USE;
+		}
+		return EConnectionStatus.NONE;
+	}
+
+	private void removeConnection(IConnection connection) {
+		handledConnections.remove(connection);
+	}
+
+	private IConnection2 findConnection(IConnectedService cs) {
+		for (IConnection2 connection : handledConnections) {
+			for (IConnectedService connectedService : manager.getConnectedServices(connection)) {
+				if (cs.equals(connectedService))
+					return connection;
+			}
+		}
+		return null;
+	}
+
+	public void handleServiceStatusChange(IStatus status) {
+		IConnectedService service = status.getConnectedService();
+		IConnection2 connection = findConnection(service);
+		if (connection != null) {
+			reconcileConnection(connection);
+		}
+	}
+
+}