Adds plugin that adds contact source services (groups to the contact list) with the monitored lines of OperationSetTelephonyBLF. Adds custom action button to pickup calls is possible.

maven 5436
Damian Minkov 12 years ago
parent bdb5b62fb1
commit e812038241

@ -1070,6 +1070,7 @@
bundle-notification-service,bundle-notification-handlers,
bundle-notification-wiring,bundle-notification-config,
bundle-contacteventhandler,
bundle-plugin-blf,
bundle-plugin-contactinfo,bundle-plugin-chatalerter, bundle-keybindings,
bundle-plugin-keybindingChooser,bundle-plugin-globalproxyconfig,
bundle-jfontchooserlib,bundle-update,bundle-plugin-update,
@ -2753,6 +2754,15 @@ org.bouncycastle.util"/>
</jar>
</target>
<!--BUNDLE-PLUGIN-BLF-->
<target name="bundle-plugin-blf">
<jar compress="false" destfile="${bundles.dest}/plugin-blf.jar"
manifest="${src}/net/java/sip/communicator/plugin/busylampfield/busylampfield.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/plugin/busylampfield"
prefix="net/java/sip/communicator/plugin/busylampfield"/>
</jar>
</target>
<!--BUNDLE-PLUGIN-SpellChecker-->
<target name="bundle-plugin-spellcheck">
<jar compress="false" destfile="${bundles.dest}/spellChecker.jar"

@ -202,6 +202,7 @@ felix.auto.start.67= \
reference:file:sc-bundles/plugin-msofficecomm.jar \
reference:file:sc-bundles/plugin-ldap.jar \
reference:file:sc-bundles/plugin-contactsourceconfig.jar \
reference:file:sc-bundles/plugin-blf.jar \
reference:file:sc-bundles/plugin-certconfig.jar \
reference:file:sc-bundles/phonenumbercontactsource.jar \
reference:file:sc-bundles/demuxcontactsource.jar \

@ -525,6 +525,12 @@ service.protocol.facebook.FACEBOOK_48x48=resources/images/protocol/facebook/face
plugin.branding.ABOUT_WINDOW_BACKGROUND=resources/images/plugin/branding/aboutWindowBackground.png
plugin.branding.SPLASH_SCREEN_BACKGROUND=resources/images/plugin/branding/splashScreenBackground.png
#plugin busylampfield
plugin.busylampfield.PICKUP_CALL=resources/images/impl/gui/buttons/pickupCall.png
plugin.busylampfield.PICKUP_CALL_PRESSED=resources/images/impl/gui/buttons/pickupCallPressed.png
plugin.busylampfield.PICKUP_CALL_ROLLOVER=resources/images/impl/gui/buttons/pickupCallRollover.png
# general config plugin icons
plugin.generalconfig.PLUGIN_ICON=resources/images/plugin/generalconfig/configureIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -990,6 +990,8 @@ plugin.branding.LICENSE=<DIV color={0}><b>Jitsi</b> is distributed under \
the terms of the LGPL (<a href=\"http://www.gnu.org\">\
http://www.gnu.org</a>).</DIV>
plugin.busylampfield.PICKUP=Pickup call
# Dict protocol
service.protocol.DICTIONARIES=Dictionaries
plugin.dictaccregwizz.ANY_DICTIONARY=Any Dictionary

@ -0,0 +1,249 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.customcontactactions.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.configuration.*;
import org.osgi.framework.*;
import java.util.*;
/**
* OSGi Activator for the Busy Lamp Field Plugin.
*
* @author Damian Minkov
*/
public class BLFActivator
implements BundleActivator,
ServiceListener,
BLFStatusListener
{
/**
* The bundle context.
*/
static BundleContext bundleContext;
/**
* Property to enable/disable this plugin.
*/
private static final String BLF_PLUGIN_ENABLED =
"net.java.sip.communicator.plugin.busylampfield.ENABLED";
/**
* The name of default group name if none is present.
*/
private static final String BLF_DEFAULT_GROUP_NAME = "Monitored Lines";
/**
* List of currently registered contact source services for the
* corresponding group.
*/
private Map<String, ServiceRegistration<ContactSourceService>>
currentBLFGroups = new LinkedHashMap
<String, ServiceRegistration<ContactSourceService>>();
/**
* Starts implementation.
*
* @param bundleContext
* @throws Exception
*/
@Override
public void start(BundleContext bundleContext)
throws Exception
{
ConfigurationService config = ServiceUtils.getService(
bundleContext, ConfigurationService.class);
if(!config.getBoolean(BLF_PLUGIN_ENABLED, false))
return;
BLFActivator.bundleContext = bundleContext;
bundleContext.addServiceListener(this);
initProviders();
bundleContext.registerService(
CustomContactActionsService.class.getName(),
new CustomActionsBLFSourceContact(),
null
);
}
/**
* Stops.
* @param bundleContext
* @throws Exception
*/
@Override
public void stop(BundleContext bundleContext)
throws Exception
{}
/**
* Listens for registered providers.
* @param serviceEvent
*/
@Override
public void serviceChanged(ServiceEvent serviceEvent)
{
ServiceReference<?> serviceRef = serviceEvent.getServiceReference();
// if the event is caused by a bundle being stopped, we don't want to
// know
if(serviceRef.getBundle().getState() == Bundle.STOPPING)
return;
Object service = bundleContext.getService(serviceRef);
// we don't care if the source service is not a protocol provider
if(!(service instanceof ProtocolProviderService))
return;
switch(serviceEvent.getType())
{
case ServiceEvent.REGISTERED:
handleProviderAdded((ProtocolProviderService) service);
break;
case ServiceEvent.UNREGISTERING:
handleProviderRemoved((ProtocolProviderService) service);
break;
}
}
/**
* Initializes all currently registered protocol providers that contain
* the desired operation set.
*/
private void initProviders()
{
for(ServiceReference<ProtocolProviderService> serRef :
ServiceUtils.getServiceReferences(
bundleContext, ProtocolProviderService.class))
{
handleProviderAdded(bundleContext.getService(serRef));
}
}
/**
* Adds a protocol provider, when such provider is registered.
*
* @param protocolProvider the <tt>ProtocolProviderService</tt> to add
*/
private void handleProviderAdded(ProtocolProviderService protocolProvider)
{
OperationSetTelephonyBLF opset =
protocolProvider.getOperationSet(OperationSetTelephonyBLF.class);
if(opset == null)
return;
opset.addStatusListener(this);
for(OperationSetTelephonyBLF.Line line
: opset.getCurrentlyMonitoredLines())
{
String groupName = line.getGroup();
if(groupName == null)
groupName = BLF_DEFAULT_GROUP_NAME;
ServiceRegistration<ContactSourceService> serviceReg
= currentBLFGroups.get(groupName);
if(serviceReg != null)
{
BLFContactSourceService css
= (BLFContactSourceService)bundleContext.getService(
serviceReg.getReference());
css.addLine(line);
continue;
}
else
{
BLFContactSourceService css
= new BLFContactSourceService(
groupName, currentBLFGroups.size() + 1);
serviceReg = (ServiceRegistration<ContactSourceService>)
bundleContext.registerService(
ContactSourceService.class.getName(),
css,
null);
currentBLFGroups.put(groupName, serviceReg);
css.addLine(line);
}
}
}
/**
* Removes a protocol provider from the list when unregistered.
* @param protocolProvider the <tt>ProtocolProviderService</tt> to remove
*/
private void handleProviderRemoved(ProtocolProviderService protocolProvider)
{
OperationSetTelephonyBLF opset =
protocolProvider.getOperationSet(OperationSetTelephonyBLF.class);
if(opset == null)
return;
opset.removeStatusListener(this);
for(OperationSetTelephonyBLF.Line line
: opset.getCurrentlyMonitoredLines())
{
String groupName = line.getGroup();
if(groupName == null)
groupName = BLF_DEFAULT_GROUP_NAME;
ServiceRegistration<ContactSourceService> serviceReg
= currentBLFGroups.remove(groupName);
if(serviceReg == null)
continue;
serviceReg.unregister();
}
}
/**
* Called whenever a change occurs in the BLFStatus of one of the
* monitored lines that we have subscribed for.
* @param event the BLFStatusEvent describing the status change.
*/
@Override
public void blfStatusChanged(BLFStatusEvent event)
{
if(!(event.getSource() instanceof OperationSetTelephonyBLF.Line))
return;
OperationSetTelephonyBLF.Line line
= (OperationSetTelephonyBLF.Line)event.getSource();
String gr = line.getGroup();
if(gr == null)
gr = BLF_DEFAULT_GROUP_NAME;
ServiceRegistration<ContactSourceService> serviceReg
= currentBLFGroups.get(gr);
if(serviceReg == null)
return;
BLFContactSourceService css
= (BLFContactSourceService)bundleContext.getService(
serviceReg.getReference());
css.updateLineStatus(line, event.getType());
}
}

@ -0,0 +1,152 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import java.util.*;
/**
* The query that will update lines.
*
* @author Damian Minkov
*/
public class BLFContactQuery
extends AbstractContactQuery<BLFContactSourceService>
{
/**
* The query string.
*/
private String queryString;
/**
* The query result list.
*/
private final List<SourceContact> results;
/**
* Constructs new query.
*
* @param parentService the parent contact source service
* @param queryString the query string
* @param contactCount contacts to process, not used currently.
*/
public BLFContactQuery(
BLFContactSourceService parentService,
Collection<OperationSetTelephonyBLF.Line> monitoredLines,
String queryString, int contactCount)
{
super(parentService);
this.queryString = queryString;
this.results = new ArrayList<SourceContact>();
for(OperationSetTelephonyBLF.Line line : monitoredLines)
{
addLine(line, false);
}
}
/**
* Returns the query string.
*
* @return the query string
*/
@Override
public String getQueryString()
{
return queryString;
}
/**
* Returns the list of query results.
*
* @return the list of query results
*/
@Override
public List<SourceContact> getQueryResults()
{
return results;
}
/**
* Starts this <tt>BLFContactQuery</tt>.
*/
@Override
public void start()
{
for(SourceContact sc : results)
{
fireContactReceived(sc, false);
}
}
/**
* Adds new line to display.
* @param line to display status.
* @param fireEvent whether to fire events
*/
void addLine(OperationSetTelephonyBLF.Line line, boolean fireEvent)
{
for(SourceContact sc : results)
{
BLFSourceContact blfSC = (BLFSourceContact)sc;
if(blfSC.getLine().equals(line))
return;
}
BLFSourceContact sc
= new BLFSourceContact(getContactSource(), line);
results.add(sc);
if(fireEvent)
fireContactReceived(sc, false);
}
/**
* Updates the source contact status.
* @param line
* @param status
*/
void updateLineStatus(OperationSetTelephonyBLF.Line line, int status)
{
for(SourceContact sc : results)
{
BLFSourceContact blfSC = (BLFSourceContact)sc;
if(blfSC.getLine().equals(line))
{
blfSC.setPresenceStatus(getPresenceStatus(status));
fireContactChanged(blfSC);
break;
}
}
}
/**
* Maps BLFStatusEvent.type to BLFPresenceStatus.
* @param status the staus to map.
* @return the corresponding BLFPresenceStatus.
*/
private BLFPresenceStatus getPresenceStatus(int status)
{
switch(status)
{
case BLFStatusEvent.STATUS_BUSY:
return BLFPresenceStatus.BLF_BUSY;
case BLFStatusEvent.STATUS_OFFLINE:
return BLFPresenceStatus.BLF_OFFLINE;
case BLFStatusEvent.STATUS_RINGING:
return BLFPresenceStatus.BLF_RINGING;
case BLFStatusEvent.STATUS_FREE:
return BLFPresenceStatus.BLF_FREE;
default:
return null;
}
}
}

@ -0,0 +1,158 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.Logger;
import org.jitsi.util.*;
import java.util.*;
/**
* The contact source service to manage query and lines.
*
* @author Damian Minkov
*/
public class BLFContactSourceService
implements ContactSourceService
{
/**
* The <tt>Logger</tt> used by the
* <tt>ConfCallsContactSource</tt> class for logging output.
*/
private static final Logger logger
= Logger.getLogger(BLFContactSourceService.class);
/**
* Type of a recent messages source.
*/
public static final int BLF_TYPE = CONTACT_LIST_TYPE;
/**
* Constants to display name <tt>ContactSource</tt>.
*/
private final String displayName;
/**
* The latest query.
*/
private BLFContactQuery ourContactQuery = null;
/**
* The list of lines this service will handle.
*/
private Set<OperationSetTelephonyBLF.Line> monitoredLines
= new HashSet<OperationSetTelephonyBLF.Line>();
/**
* The current group index.
*/
private final int index;
/**
* Constructs.
* @param displayName
*/
public BLFContactSourceService(String displayName, int index)
{
this.displayName = displayName;
this.index = index;
}
/**
* Returns the identifier of this contact source. Some of the common
* identifiers are defined here (For example the CALL_HISTORY identifier
* should be returned by all call history implementations of this interface)
* @return the identifier of this contact source
*/
@Override
public int getType()
{
return BLF_TYPE;
}
/**
* Returns a user-friendly string that identifies this contact source.
* @return the display name of this contact source
*/
@Override
public String getDisplayName()
{
return displayName;
}
/**
* Queries this search source for the given <tt>queryString</tt>.
* @param queryString the string to search for
* @return the created query
*/
@Override
public ContactQuery createContactQuery(String queryString)
{
return createContactQuery(queryString, 20);
}
/**
* Queries this search source for the given <tt>queryString</tt>.
*
* @param queryString the string to search for
* @param contactCount the maximum count of result contacts
* @return the created query
*/
@Override
public ContactQuery createContactQuery(String queryString, int contactCount)
{
if(!StringUtils.isNullOrEmpty(queryString))
return null;
if(ourContactQuery == null)
ourContactQuery = new BLFContactQuery(
this, monitoredLines, queryString, contactCount);
return ourContactQuery;
}
/**
* Returns the index of the contact source in the result list.
*
* @return the index of the contact source in the result list
*/
@Override
public int getIndex()
{
// shift it with 2 position (recent messages-0 and chat rooms-1),
// counting from 0
return 1 + index;
}
/**
* Adds new line to display.
* @param line to display status.
*/
void addLine(OperationSetTelephonyBLF.Line line)
{
monitoredLines.add(line);
if(ourContactQuery != null)
ourContactQuery.addLine(line, true);
}
/**
* Updates the source contact status.
* @param line
* @param status
*/
void updateLineStatus(OperationSetTelephonyBLF.Line line, int status)
{
if(ourContactQuery == null)
return;
ourContactQuery.updateLineStatus(line, status);
}
}

@ -0,0 +1,77 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.protocol.*;
/**
* The status to display for the contact srouces.
* @author Damian Minkov
*/
public class BLFPresenceStatus
extends PresenceStatus
{
/**
* The Online status. Indicate that the line is available and free.
*/
public static final String AVAILABLE = "Available";
/**
* On The Phone Chat status.
* Indicates that the line is used.
*/
public static final String BUSY = "Busy";
/**
* Ringing status.
* Indicates that the line is currently ringing.
*/
public static final String RINGING = "On the phone";
/**
* Indicates an Offline status or status with 0 connectivity.
*/
public static final String OFFLINE = "Offline";
/**
* The Online status. Indicate that the line is free.
*/
public static final BLFPresenceStatus BLF_FREE = new BLFPresenceStatus(
65, AVAILABLE);
/**
* The Offline status. Indicates the line status retrieval
* is not available.
*/
public static final BLFPresenceStatus BLF_OFFLINE = new BLFPresenceStatus(
0, OFFLINE);
/**
* Indicates an On The Phone status.
*/
public static final BLFPresenceStatus BLF_BUSY = new BLFPresenceStatus(
30, BUSY);
/**
* Indicates Ringing status.
*/
public static final BLFPresenceStatus BLF_RINGING = new BLFPresenceStatus(
31, RINGING);
/**
* Creates an instance of <tt>BLFPresenceStatus</tt> with the
* specified parameters.
*
* @param status the connectivity level of the new presence status
* instance
* @param statusName the name of the presence status.
*/
private BLFPresenceStatus(int status, String statusName)
{
super(status, statusName);
}
}

@ -0,0 +1,47 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.protocol.*;
import java.util.*;
/**
* The BLF source contact.
* @author Damian Minkov
*/
public class BLFSourceContact
extends GenericSourceContact
{
private final OperationSetTelephonyBLF.Line line;
/**
* Initializes a new <tt>AddrBookSourceContact</tt> instance.
*
* @param contactSource the <tt>ContactSourceService</tt> which is creating
* the new instance
*/
public BLFSourceContact(ContactSourceService contactSource,
OperationSetTelephonyBLF.Line line)
{
super(contactSource,
line.getName() != null ? line.getName() : line.getAddress(),
new ArrayList<ContactDetail>());
this.line = line;
}
/**
* Returns the line displayed.
* @return
*/
public OperationSetTelephonyBLF.Line getLine()
{
return line;
}
}

@ -0,0 +1,188 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.busylampfield;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.customcontactactions.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
import java.util.*;
/**
* Custom acction to show pickup call button.
*
* @author Damian Minkov
*/
public class CustomActionsBLFSourceContact
implements CustomContactActionsService<SourceContact>
{
/**
* Our logger.
*/
private final Logger logger = Logger.getLogger(
CustomActionsBLFSourceContact.class);
/**
* List of actions.
*/
private final List<ContactAction<SourceContact>> actionsList
= new LinkedList<ContactAction<SourceContact>>();
public CustomActionsBLFSourceContact()
{
actionsList.add(new PickupAction());
}
/**
* Returns the template class that this service has been initialized with
*
* @return the template class
*/
@Override
public Class<SourceContact> getContactSourceClass()
{
return SourceContact.class;
}
/**
* Returns all custom actions defined by this service.
*
* @return an iterator over a list of <tt>ContactAction</tt>s
*/
@Override
public Iterator<ContactAction<SourceContact>> getCustomContactActions()
{
return actionsList.iterator();
}
/**
* Returns all custom actions menu items defined by this service.
*
* @return an iterator over a list of <tt>ContactActionMenuItem</tt>s
*/
@Override
public Iterator<ContactActionMenuItem<SourceContact>>
getCustomContactActionsMenuItems()
{
return null;
}
/**
* Action that represents pickup button.
*/
private class PickupAction
implements ContactAction<SourceContact>
{
/**
* Invoked when an action occurs.
*
* @param actionSource the source of the action
* @param x the x coordinate of the action
* @param y the y coordinate of the action
*/
@Override
public void actionPerformed(final SourceContact actionSource, int x, int y)
throws
OperationFailedException
{
if(!(actionSource instanceof BLFSourceContact))
return;
new Thread(new Runnable()
{
public void run()
{
try
{
OperationSetTelephonyBLF.Line line
= ((BLFSourceContact)actionSource).getLine();
OperationSetTelephonyBLF opset =
line.getProvider().getOperationSet(
OperationSetTelephonyBLF.class);
opset.pickup(line);
}
catch(Exception ex)
{
logger.error("Error picking up call", ex);
}
}
}).start();
}
/**
* The icon used by the UI to visualize this action.
* @return the button icon.
*/
@Override
public byte[] getIcon()
{
return ResourceManagementServiceUtils.getService(
BLFActivator.bundleContext).getImageInBytes(
"plugin.busylampfield.PICKUP_CALL");
}
/**
* The icon used by the UI to visualize this action.
* @return the button icon.
*/
@Override
public byte[] getRolloverIcon()
{
return ResourceManagementServiceUtils.getService(
BLFActivator.bundleContext).getImageInBytes(
"plugin.busylampfield.PICKUP_CALL_ROLLOVER");
}
/**
* The icon used by the UI to visualize this action.
* @return the button icon.
*/
@Override
public byte[] getPressedIcon()
{
return ResourceManagementServiceUtils.getService(
BLFActivator.bundleContext).getImageInBytes(
"plugin.busylampfield.PICKUP_CALL_PRESSED");
}
/**
* Returns the tool tip text of the component to create for this contact
* action.
*
* @return the tool tip text of the component to create for this contact
* action
*/
@Override
public String getToolTipText()
{
return ResourceManagementServiceUtils.getService(
BLFActivator.bundleContext).getI18NString(
"plugin.busylampfield.PICKUP");
}
/**
* Indicates if this action is visible for the
* given <tt>actionSource</tt>.
*
* @param actionSource the action source for which we're verifying the
* action.
* @return <tt>true</tt> if the action should be visible for the given
* <tt>actionSource</tt>, <tt>false</tt> - otherwise
*/
@Override
public boolean isVisible(SourceContact actionSource)
{
if(actionSource.getPresenceStatus()
.equals(BLFPresenceStatus.BLF_RINGING))
return true;
else
return false;
}
}
}

@ -0,0 +1,14 @@
Bundle-Activator: net.java.sip.communicator.plugin.busylampfield.BLFActivator
Bundle-Name: Busy Lamp Field Plugin
Bundle-Description: Contact Sources that show and control BLF operation sets
Bundle-Vendor: jitsi.org
Bundle-Version: 0.0.1
Bundle-SymbolicName: net.java.sip.communicator.plugin.busylampfield
Import-Package: org.osgi.framework,
org.jitsi.service.configuration,
net.java.sip.communicator.service.contactsource,
net.java.sip.communicator.service.customcontactactions,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.service.resources, org.jitsi.service.resources,
net.java.sip.communicator.util, org.jitsi.util
Loading…
Cancel
Save