/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.impl.protocol.mock; import java.text.*; import java.util.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.media.*; import net.java.sip.communicator.util.*; /** * A mock implementation of a basic telephony operation set * * @author Damian Minkov */ public class MockOperationSetBasicTelephony extends AbstractOperationSetBasicTelephony<MockProvider> implements CallChangeListener { private static final Logger logger = Logger.getLogger(MockOperationSetBasicTelephony.class); /** * A reference to the <tt>ProtocolProviderServiceSipImpl</tt> instance * that created us. */ private MockProvider protocolProvider = null; /** * A table mapping call ids against call instances. */ private Hashtable<String, Call> activeCalls = new Hashtable<String, Call>(); public MockOperationSetBasicTelephony(MockProvider protocolProvider) { this.protocolProvider = protocolProvider; } /** * Indicates a user request to answer an incoming call from the specified * CallPeer. * * @param peer the call peer that we'd like to answer. * @throws OperationFailedException with the corresponding code if we * encounter an error while performing this operation. */ public void answerCallPeer(CallPeer peer) throws OperationFailedException { MockCallPeer callPeer = (MockCallPeer)peer; if(peer.getState().equals(CallPeerState.CONNECTED)) { if (logger.isInfoEnabled()) logger.info("Ignoring user request to answer a CallPeer " + "that is already connected. CP:" + peer); return; } callPeer.setState(CallPeerState.CONNECTED, null); } /** * {@inheritDoc} * * Ignores the <tt>CallConference</tt> argument. */ public Call createCall(String callee, CallConference conference) throws OperationFailedException, ParseException { return createNewCall(callee); } /** * Creates a new <tt>Call</tt> and invites a specific <tt>CallPeer</tt> * given by her <tt>Contact</tt> to it. * * @param callee the address of the callee who we should invite to a new * call * @param calleeResource the specific resource to which the invite should be * sent * @param conference the <tt>CallConference</tt> in which the newly-created * <tt>Call</tt> is to participate * @return a newly created <tt>Call</tt>. The specified <tt>callee</tt> is * available in the <tt>Call</tt> as a <tt>CallPeer</tt> * @throws OperationFailedException with the corresponding code if we fail * to create the call */ public Call createCall(Contact callee, ContactResource calleeResource, CallConference conference) throws OperationFailedException { // We don't support callee resource. return createCall(callee, conference); } private Call createNewCall(String address) { MockCall newCall = new MockCall(protocolProvider); newCall.addCallChangeListener(this); activeCalls.put(newCall.getCallID(), newCall); new MockCallPeer(address, newCall); return newCall; } /** * Returns an iterator over all currently active calls. * * @return Iterator */ public Iterator<Call> getActiveCalls() { return activeCalls.values().iterator(); } /** * Indicates a user request to end a call with the specified call * particiapnt. * * @param peer the peer that we'd like to hang up on. * @throws OperationFailedException with the corresponding code if we * encounter an error while performing this operation. */ public void hangupCallPeer(CallPeer peer) throws OperationFailedException { //do nothing if the call is already ended if (peer.getState().equals(CallPeerState.DISCONNECTED)) { if (logger.isDebugEnabled()) logger.debug("Ignoring a request to hangup a call peer " +"that is already DISCONNECTED"); return; } MockCallPeer callPeer = (MockCallPeer)peer; if (logger.isInfoEnabled()) logger.info("hangupCallPeer"); callPeer.setState(CallPeerState.DISCONNECTED, null); } /** * Ends the call with the specified <tt>peer</tt>. * * @param peer the peer that we'd like to hang up on. * @param reasonCode indicates if the hangup is following to a call failure or * simply a disconnect indicate by the reason. * @param reason the reason of the hangup. If the hangup is due to a call * failure, then this string could indicate the reason of the failure * * @throws OperationFailedException if we fail to terminate the call. */ public void hangupCallPeer(CallPeer peer, int reasonCode, String reason) throws OperationFailedException { hangupCallPeer(peer); } /** * Resumes communication with a call peer previously put on hold. * * @param peer the call peer to put on hold. * @todo Implement this * net.java.sip.communicator.service.protocol.OperationSetBasicTelephony * method */ public void putOffHold(CallPeer peer) { } /** * Puts the specified CallPeer "on hold". * * @param peer the peer that we'd like to put on hold. * @throws OperationFailedException with the corresponding code if we * encounter an error while performing this operation. * @todo Implement this * net.java.sip.communicator.service.protocol.OperationSetBasicTelephony * method */ public void putOnHold(CallPeer peer) throws OperationFailedException { } public Call receiveCall(String fromAddress) throws Exception { Call newCall = createCall(fromAddress); fireCallEvent(CallEvent.CALL_RECEIVED, newCall); return newCall; } public Call placeCall(String toAddress) throws Exception { Call newCall = createCall(toAddress); fireCallEvent(CallEvent.CALL_INITIATED, newCall); // must have one peer MockCallPeer callPArt = (MockCallPeer)newCall.getCallPeers().next(); callPArt.setState(CallPeerState.ALERTING_REMOTE_SIDE, "no reason"); callPArt.setState(CallPeerState.CONNECTED, "no reason"); return newCall; } public CallPeer addNewCallPeer(Call call, String address) { MockCallPeer callPArt = new MockCallPeer(address, (MockCall)call); callPArt.setState(CallPeerState.ALERTING_REMOTE_SIDE, "no reason"); callPArt.setState(CallPeerState.CONNECTED, "no reason"); return callPArt; } public void callPeerAdded(CallPeerEvent evt) { } public void callPeerRemoved(CallPeerEvent evt) { } public void callStateChanged(CallChangeEvent evt) { if(evt.getEventType().equals(CallChangeEvent.CALL_STATE_CHANGE) && ((CallState)evt.getNewValue()).equals(CallState.CALL_ENDED)) { MockCall sourceCall = (MockCall)this.activeCalls .remove(evt.getSourceCall().getCallID()); if (logger.isTraceEnabled()) logger.trace( "Removing call " + sourceCall + " from the list of " + "active calls because it entered an ENDED state"); fireCallEvent(CallEvent.CALL_ENDED, sourceCall); } } /** * Returns the protocol provider that this operation set belongs to. * * @return a reference to the <tt>ProtocolProviderService</tt> that created * this operation set. */ public MockProvider getProtocolProvider() { return protocolProvider; } }