CallPeer methods with the purpose of only leaving custom
* protocol development to clients using the PhoneUI service.
*
* @author Emil Ivov
* @author Lubomir Marinov
* @author Yana Stamcheva
*/
public abstract class AbstractCallPeer
extends PropertyChangeNotifier
implements CallPeer
{
private static final Logger logger
= Logger.getLogger(AbstractCallPeer.class);
/**
* The constant which describes an empty set of
* ConferenceMembers (and which can be used to reduce
* allocations).
*/
protected static final ConferenceMember[] NO_CONFERENCE_MEMBERS
= new ConferenceMember[0];
/**
* All the CallPeer listeners registered with this CallPeer.
*/
protected final ListConferenceMember such as {@link #getConferenceMembers()} and
* {@link #getConferenceMemberCount()}.
*/
private boolean conferenceFocus;
/**
* The list of ConferenceMembers currently known to and managed
* in a conference by this peer.
*/
private final ListCallPeerConferenceListeners interested in
* and to be notified about changes in conference-related information such
* as this peer acting or not acting as a conference focus and
* conference membership details.
*/
protected final ListCallPeer transitioned
* into a state (likely {@link CallPeerState#CONNECTED}) marking the
* start of the duration of the participation in a Call.
*
* @return the time at which this CallPeer transitioned
* into a state marking the start of the duration of the
* participation in a Call or
* {@link CallPeer#CALL_DURATION_START_TIME_UNKNOWN} if such
* a transition has not been performed
*/
public long getCallDurationStartTime()
{
return callDurationStartTime;
}
/**
* Determines whether the audio stream (if any) being sent to this
* peer is mute.
* * The default implementation returns false. *
* * @return true if an audio stream is being sent to this * peer and it is currently mute; false, otherwise */ public boolean isMute() { return isMute; } /** * Sets the mute property for this call peer. * * @param newMuteValue the new value of the mute property for this call peer */ public void setMute(boolean newMuteValue) { this.isMute = newMuteValue; firePropertyChange(MUTE_PROPERTY_NAME, isMute, newMuteValue); } /** * Determines whether this call peer is currently a conference focus. * * @return true if this peer is a conference focus and * false otherwise. */ public boolean isConferenceFocus() { return conferenceFocus; } /** * Specifies whether this peer is a conference focus. * * @param conferenceFocus true if this peer is to become a * conference focus and false otherwise. */ public void setConferenceFocus(boolean conferenceFocus) { if (this.conferenceFocus != conferenceFocus) { this.conferenceFocus = conferenceFocus; fireCallPeerConferenceEvent( new CallPeerConferenceEvent( this, CallPeerConferenceEvent.CONFERENCE_FOCUS_CHANGED)); } } /** * Implements CallPeer#getConferenceMembers(). In order to reduce * allocations, returns #NO_CONFERENCE_MEMBERS if #conferenceMembers * contains no ConferenceMember instances. * @return an array of the conference members */ public ConferenceMember[] getConferenceMembers() { ConferenceMember[] conferenceMembers; synchronized (this.conferenceMembers) { int conferenceMemberCount = this.conferenceMembers.size(); if (conferenceMemberCount <= 0) conferenceMembers = NO_CONFERENCE_MEMBERS; else conferenceMembers = this.conferenceMembers .toArray( new ConferenceMember[conferenceMemberCount]); } return conferenceMembers; } /** * Returns the count of the members contained in this peer. *
* Implements CallPeer#getConferenceMemberCount().
* @return the count of the members contained in this peer
*/
public int getConferenceMemberCount()
{
return conferenceMembers.size();
}
/**
* Adds a specific ConferenceMember to the list of
* ConferenceMembers reported by this peer through
* {@link #getConferenceMembers()} and {@link #getConferenceMemberCount()}
* and fires
* CallPeerConferenceEvent#CONFERENCE_MEMBER_ADDED to
* the currently registered CallPeerConferenceListeners.
*
* @param conferenceMember
* a ConferenceMember to be added to the list of
* ConferenceMember reported by this peer. If
* the specified ConferenceMember is already
* contained in the list, it is not added again and no event is
* fired.
*/
public void addConferenceMember(ConferenceMember conferenceMember)
{
if (conferenceMember == null)
throw new NullPointerException("conferenceMember");
synchronized (conferenceMembers)
{
if (conferenceMembers.contains(conferenceMember))
return;
conferenceMembers.add(conferenceMember);
}
fireCallPeerConferenceEvent(
new CallPeerConferenceEvent(
this,
CallPeerConferenceEvent.CONFERENCE_MEMBER_ADDED,
conferenceMember));
}
/**
* Removes a specific ConferenceMember from the list of
* ConferenceMembers reported by this peer through
* {@link #getConferenceMembers()} and {@link #getConferenceMemberCount()}
* if it is contained and fires
* CallPeerConferenceEvent#CONFERENCE_MEMBER_REMOVED to
* the currently registered CallPeerConferenceListeners.
*
* @param conferenceMember
* a ConferenceMember to be removed from the list of
* ConferenceMember reported by this peer. If
* the specified ConferenceMember is no contained in
* the list, no event is fired.
*/
public void removeConferenceMember(ConferenceMember conferenceMember)
{
if (conferenceMember == null)
throw new NullPointerException("conferenceMember");
synchronized (conferenceMembers)
{
if (!conferenceMembers.remove(conferenceMember))
return;
}
fireCallPeerConferenceEvent(
new CallPeerConferenceEvent(
this,
CallPeerConferenceEvent.CONFERENCE_MEMBER_REMOVED,
conferenceMember));
}
/**
* ImplementsCallPeer#addCallPeerConferenceListener(
* CallPeerConferenceListener). In the fashion of the addition of the
* other listeners, does not throw an exception on attempting to add a null
* listeners and just ignores the call.
* @param listener the CallPeerConferenceListener to add
*/
public void addCallPeerConferenceListener(
CallPeerConferenceListener listener)
{
if (listener != null)
synchronized (callPeerConferenceListeners)
{
if (!callPeerConferenceListeners.contains(listener))
callPeerConferenceListeners.add(listener);
}
}
/**
* Implements CallPeer#removeCallPeerConferenceListener(
* CallPeerConferenceListener).
* @param listener the CallPeerConferenceListener to remove
*/
public void removeCallPeerConferenceListener(
CallPeerConferenceListener listener)
{
if (listener != null)
synchronized (callPeerConferenceListeners)
{
callPeerConferenceListeners.remove(listener);
}
}
/**
* Adds a specific StreamSoundLevelListener to the list of
* listeners interested in and notified about changes in stream sound level
* related information.
*
* @param listener the StreamSoundLevelListener to add
*/
public void addStreamSoundLevelListener(StreamSoundLevelListener listener)
{
if (listener != null)
synchronized (streamSoundLevelListeners)
{
streamSoundLevelListeners.add(listener);
}
}
/**
* Removes a specific StreamSoundLevelListener of the list of
* listeners interested in and notified about changes in stream sound level
* related information.
*
* @param listener the StreamSoundLevelListener to remove
*/
public void removeStreamSoundLevelListener(
StreamSoundLevelListener listener)
{
if (listener != null)
synchronized (streamSoundLevelListeners)
{
streamSoundLevelListeners.remove(listener);
}
}
/**
* Adds a specific ConferenceMembersSoundLevelListener to the list
* of listeners interested in and notified about changes in conference
* members sound level.
*
* @param listener the ConferenceMembersSoundLevelListener to add
*/
public void addConferenceMembersSoundLevelListener(
ConferenceMembersSoundLevelListener listener)
{
if (listener != null)
synchronized (membersSoundLevelListeners)
{
membersSoundLevelListeners.add(listener);
}
}
/**
* Removes a specific ConferenceMembersSoundLevelListener of the
* list of listeners interested in and notified about changes in conference
* members sound level.
*
* @param listener the ConferenceMembersSoundLevelListener to
* remove
*/
public void removeConferenceMembersSoundLevelListener(
ConferenceMembersSoundLevelListener listener)
{
if (listener != null)
synchronized (membersSoundLevelListeners)
{
membersSoundLevelListeners.remove(listener);
}
}
/**
* Fires a specific CallPeerConferenceEvent to the
* CallPeerConferenceListeners interested in changes in
* the conference-related information provided by this peer.
*
* @param conferenceEvent
* a CallPeerConferenceEvent to be fired and
* carrying the event data
*/
protected void fireCallPeerConferenceEvent(
CallPeerConferenceEvent conferenceEvent)
{
CallPeerConferenceListener[] listeners;
synchronized (callPeerConferenceListeners)
{
listeners
= callPeerConferenceListeners
.toArray(
new CallPeerConferenceListener[
callPeerConferenceListeners.size()]);
}
int eventID = conferenceEvent.getEventID();
for (CallPeerConferenceListener listener : listeners)
switch (eventID)
{
case CallPeerConferenceEvent.CONFERENCE_FOCUS_CHANGED:
listener.conferenceFocusChanged(conferenceEvent);
break;
case CallPeerConferenceEvent.CONFERENCE_MEMBER_ADDED:
listener.conferenceMemberAdded(conferenceEvent);
break;
case CallPeerConferenceEvent.CONFERENCE_MEMBER_REMOVED:
listener.conferenceMemberRemoved(conferenceEvent);
break;
}
}
/**
* Fires a StreamSoundLevelEvent and notifies all registered
* listeners.
*
* @param level the new sound level
*/
public void fireStreamSoundLevelEvent(int level)
{
StreamSoundLevelEvent event
= new StreamSoundLevelEvent(this, level);
StreamSoundLevelListener[] listeners;
synchronized(streamSoundLevelListeners)
{
listeners = streamSoundLevelListeners.toArray(
new StreamSoundLevelListener[streamSoundLevelListeners.size()]);
}
for (StreamSoundLevelListener listener : listeners)
{
listener.streamSoundLevelChanged(event);
}
}
/**
* Fires a ConferenceMembersSoundLevelListener and notifies all
* registered listeners.
*
* @param levels the new conference members sound levels
*/
public void fireConferenceMembersSoundLevelEvent(
Map