aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl
diff options
context:
space:
mode:
authorLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-09-10 15:23:37 +0000
committerLyubomir Marinov <lyubomir.marinov@jitsi.org>2010-09-10 15:23:37 +0000
commitd613851fa2aa6f19b1ab5c8d89f471398f0168c0 (patch)
tree3582f303f559fb3d611dfe8fb0f5eedc294b513e /src/net/java/sip/communicator/impl
parent21c58834fb806aacd5ad154f803ec2ef17a0923e (diff)
downloadjitsi-d613851fa2aa6f19b1ab5c8d89f471398f0168c0.zip
jitsi-d613851fa2aa6f19b1ab5c8d89f471398f0168c0.tar.gz
jitsi-d613851fa2aa6f19b1ab5c8d89f471398f0168c0.tar.bz2
- Fixes call recording-related issues reported off-list by Emil Ivov.
- Adds javadocs, fixes warnings.
Diffstat (limited to 'src/net/java/sip/communicator/impl')
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java45
-rwxr-xr-xsrc/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java16
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java14
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java160
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java77
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java63
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java25
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java21
9 files changed, 255 insertions, 168 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java b/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java
index d5bada8..c396cfa 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/RecordButton.java
@@ -137,6 +137,27 @@ public class RecordButton
}
setSelected(startedRecording);
}
+ /*
+ * Notify the user the call has been successfully saved upon the
+ * recorder stopping.
+ */
+ if (startedRecording && (recorder != null))
+ {
+ recorder.addListener(
+ new Recorder.Listener()
+ {
+ public void recorderStopped(Recorder recorder)
+ {
+ NotificationManager.fireNotification(
+ NotificationManager.CALL_SAVED,
+ resources.getI18NString(
+ "plugin.callrecordingconfig.CALL_SAVED"),
+ resources.getI18NString(
+ "plugin.callrecordingconfig.CALL_SAVED_TO",
+ new String[] { callFilename }));
+ }
+ });
+ }
}
// stop recording
else if (recorder != null)
@@ -144,13 +165,6 @@ public class RecordButton
try
{
recorder.stop();
- NotificationManager.fireNotification(
- NotificationManager.CALL_SAVED,
- resources.getI18NString(
- "plugin.callrecordingconfig.CALL_SAVED"),
- resources.getI18NString(
- "plugin.callrecordingconfig.CALL_SAVED_TO",
- new String[] { callFilename }));
}
finally
{
@@ -189,7 +203,7 @@ public class RecordButton
}
}
- String ext = configuration.getString(Recorder.CALL_FORMAT);
+ String ext = configuration.getString(Recorder.FORMAT);
// Use a default format when the configured one seems invalid.
if ((ext == null)
@@ -298,6 +312,7 @@ public class RecordButton
{
String savedCallsPath
= configuration.getString(Recorder.SAVED_CALLS_PATH);
+ String callFormat;
// Ask the user where to save the call.
if ((savedCallsPath == null) || (savedCallsPath.length() == 0))
@@ -381,7 +396,7 @@ public class RecordButton
* OS X at least) i.e. no format, then it is not obvious that we
* have to override the set Recorder.CALL_FORMAT.
*/
- String callFormat = SoundFileUtils.getExtension(selectedFile);
+ callFormat = SoundFileUtils.getExtension(selectedFile);
if ((callFormat != null) && (callFormat.length() != 0))
{
@@ -407,7 +422,7 @@ public class RecordButton
= SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
callFilename += '.' + callFormat;
}
- configuration.setProperty(Recorder.CALL_FORMAT, callFormat);
+ configuration.setProperty(Recorder.FORMAT, callFormat);
}
}
else
@@ -417,7 +432,10 @@ public class RecordButton
}
}
else
+ {
callFilename = createDefaultFilename(savedCallsPath);
+ callFormat = SoundFileUtils.getExtension(new File(callFilename));
+ }
Throwable exception = null;
@@ -426,7 +444,12 @@ public class RecordButton
Recorder recorder = getRecorder();
if (recorder != null)
- recorder.start(callFilename);
+ {
+ if ((callFormat == null) || (callFormat.length() <= 0))
+ callFormat = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
+
+ recorder.start(callFormat, callFilename);
+ }
this.recorder = recorder;
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
index c993f0e..26f4d7d 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
@@ -46,6 +46,10 @@ public class ChatConversationPanel
MouseListener,
ClipboardOwner
{
+ /**
+ * The <tt>Logger</tt> used by the <tt>ChatConversationPanel</tt> class and
+ * its instances for logging output.
+ */
private static final Logger logger
= Logger.getLogger(ChatConversationPanel.class);
@@ -335,7 +339,8 @@ public class ChatConversationPanel
* Processes the message given by the parameters.
*
* @param chatMessage the message
- * @param keyword
+ * @param keyword a substring of <tt>chatMessage</tt> to be highlighted upon
+ * display of <tt>chatMessage</tt> in the UI
* @return the processed message
*/
public String processMessage(ChatMessage chatMessage, String keyword)
@@ -1266,12 +1271,13 @@ public class ChatConversationPanel
* @param event the <tt>MouseEvent</tt>
* @return the string to be used as the tooltip for <i>event</i>.
*/
+ @Override
public String getToolTipText(MouseEvent event)
{
- if(currentHref != null && currentHref.length() != 0)
- return currentHref;
- else
- return null;
+ return
+ ((currentHref != null) && (currentHref.length() != 0))
+ ? currentHref
+ : null;
}
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java b/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java
index a3b88a9..dfb49c6 100644
--- a/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java
+++ b/src/net/java/sip/communicator/impl/neomedia/CallRecordingConfigForm.java
@@ -88,18 +88,16 @@ public class CallRecordingConfigForm
*/
private void loadValues()
{
- ConfigurationService configurationService
+ ConfigurationService configuration
= NeomediaActivator.getConfigurationService();
- String callFormat
- = configurationService.getString(Recorder.CALL_FORMAT);
+ String format = configuration.getString(Recorder.FORMAT);
formatsComboBox.setSelectedItem(
- (callFormat == null)
+ (format == null)
? SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT
- : callFormat);
+ : format);
- savedCallsDir
- = configurationService.getString(Recorder.SAVED_CALLS_PATH);
+ savedCallsDir = configuration.getString(Recorder.SAVED_CALLS_PATH);
saveCallsToCheckBox.setSelected(savedCallsDir != null);
callDirTextField.setText(savedCallsDir);
callDirTextField.setEnabled(saveCallsToCheckBox.isSelected());
@@ -192,7 +190,7 @@ public class CallRecordingConfigForm
{
NeomediaActivator
.getConfigurationService()
- .setProperty(Recorder.CALL_FORMAT, event.getItem());
+ .setProperty(Recorder.FORMAT, event.getItem());
}
}
});
diff --git a/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java b/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java
index aa37588..c8ab59c 100644
--- a/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RecorderImpl.java
@@ -13,7 +13,6 @@ import javax.media.*;
import javax.media.protocol.*;
import net.java.sip.communicator.impl.neomedia.device.*;
-import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.MediaException; // disambiguation
import net.java.sip.communicator.util.*;
@@ -28,11 +27,6 @@ import net.java.sip.communicator.util.*;
public class RecorderImpl
implements Recorder
{
- /**
- * The <tt>Logger</tt> used by the <tt>RecorderImpl</tt> class and its
- * instances for logging output.
- */
- private static final Logger logger = Logger.getLogger(RecorderImpl.class);
/**
* The list of formats in which <tt>RecorderImpl</tt> instances support
@@ -49,15 +43,22 @@ public class RecorderImpl
};
/**
+ * The <tt>AudioMixerMediaDevice</tt> which is to be or which is already
+ * being recorded by this <tt>Recorder</tt>.
+ */
+ private final AudioMixerMediaDevice device;
+
+ /**
* The <tt>MediaDeviceSession</tt> is used to create an output data source.
*/
private MediaDeviceSession deviceSession;
/**
- * The format of {@link #deviceSession} in particular and of the recording
- * produced by this <tt>Recorder</tt> in general.
+ * The <tt>List</tt> of <tt>Recorder.Listener</tt>s interested in
+ * notifications from this <tt>Recorder</tt>.
*/
- private final String format;
+ private final List<Recorder.Listener> listeners
+ = new ArrayList<Recorder.Listener>();
/**
* <tt>DataSink</tt> used to save the output data.
@@ -75,39 +76,27 @@ public class RecorderImpl
if (device == null)
throw new NullPointerException("device");
- ConfigurationService configuration
- = NeomediaActivator.getConfigurationService();
- String format = configuration.getString(Recorder.CALL_FORMAT);
+ this.device = device;
+ }
- if (format == null)
- format = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
+ /**
+ * Adds a new <tt>Recorder.Listener</tt> to the list of listeners interested
+ * in notifications from this <tt>Recorder</tt>.
+ *
+ * @param listener the new <tt>Recorder.Listener</tt> to be added to the
+ * list of listeners interested in notifications from this <tt>Recorder</tt>
+ * @see Recorder#addListener(Recorder.Listener)
+ */
+ public void addListener(Recorder.Listener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
- try
- {
- deviceSession
- = device.createRecordingSession(getContentDescriptor(
- format));
- }
- catch (IllegalArgumentException iaex)
+ synchronized (listeners)
{
- //seems like we had an illegal format stored in the configuration
- //service
- logger.debug(
- "Unable to crate a "
- + format
- + " record. Will retry default format");
-
- format = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
-
- //make sure we don't try the faulty format again.
- configuration.setProperty(Recorder.CALL_FORMAT, null);
-
- deviceSession
- = device.createRecordingSession(getContentDescriptor(
- format));
+ if (!listeners.contains(listener))
+ listeners.add(listener);
}
-
- this.format = format;
}
/**
@@ -157,24 +146,48 @@ public class RecorderImpl
}
/**
+ * Removes a existing <tt>Recorder.Listener</tt> from the list of listeners
+ * interested in notifications from this <tt>Recorder</tt>.
+ *
+ * @param listener the existing <tt>Recorder.Listener</tt> to be removed
+ * from the list of listeners interested in notifications from this
+ * <tt>Recorder</tt>
+ * @see Recorder#removeListener(Recorder.Listener)
+ */
+ public void removeListener(Recorder.Listener listener)
+ {
+ if (listener != null)
+ {
+ synchronized (listeners)
+ {
+ listeners.remove(listener);
+ }
+ }
+ }
+
+ /**
* Starts the recording of the media associated with this <tt>Recorder</tt>
* (e.g. the media being sent and received in a <tt>Call</tt>) into a file
* with a specific name.
*
+ * @param format the format into which the media associated with this
+ * <tt>Recorder</tt> is to be recorded into the specified file
* @param filename the name of the file into which the media associated with
* this <tt>Recorder</tt> is to be recorded
* @throws IOException if anything goes wrong with the input and/or output
* performed by this <tt>Recorder</tt>
* @throws MediaException if anything else goes wrong while starting the
* recording of media performed by this <tt>Recorder</tt>
- * @see Recorder#start(String)
+ * @see Recorder#start(String, String)
*/
- public void start(String filename)
+ public void start(String format, String filename)
throws IOException,
MediaException
{
if (this.sink == null)
{
+ if (format == null)
+ throw new NullPointerException("format");
if (filename == null)
throw new NullPointerException("filename");
@@ -186,18 +199,48 @@ public class RecorderImpl
int extensionBeginIndex = filename.lastIndexOf('.');
if (extensionBeginIndex < 0)
- filename += '.' + this.format;
+ filename += '.' + format;
else if (extensionBeginIndex == filename.length() - 1)
- filename += this.format;
+ filename += format;
+
+ MediaDeviceSession deviceSession = device.createSession();
+
+ try
+ {
+ deviceSession.setContentDescriptor(getContentDescriptor(format));
+
+ /*
+ * This RecorderImpl will use deviceSession to get a hold of the
+ * media being set to the remote peers associated with the same
+ * AudioMixerMediaDevice i.e. this RecorderImpl needs
+ * deviceSession to only capture and not play back.
+ */
+ deviceSession.start(MediaDirection.SENDONLY);
+
+ this.deviceSession = deviceSession;
+ }
+ finally
+ {
+ if (this.deviceSession == null)
+ {
+ throw new MediaException(
+ "Failed to create MediaDeviceSession from"
+ + " AudioMixerMediaDevice for the purposes of"
+ + " recording");
+ }
+ }
- DataSource outputDataSource = deviceSession.getOutputDataSource();
+ Throwable exception = null;
try
{
+ DataSource outputDataSource
+ = deviceSession.getOutputDataSource();
DataSink sink
= Manager.createDataSink(
outputDataSource,
new MediaLocator("file:" + filename));
+
sink.open();
sink.start();
@@ -205,10 +248,18 @@ public class RecorderImpl
}
catch (NoDataSinkException ndsex)
{
- throw
- new MediaException(
+ exception = ndsex;
+ }
+ finally
+ {
+ if ((this.sink == null) || (exception != null))
+ {
+ stop();
+
+ throw new MediaException(
"Failed to start recording into file " + filename,
- ndsex);
+ exception);
+ }
}
}
}
@@ -232,6 +283,23 @@ public class RecorderImpl
{
sink.close();
sink = null;
+
+ /*
+ * RecorderImpl creates the sink upon start() and it does it only if
+ * it is null so this RecorderImpl has really stopped only if it has
+ * managed to close() the (existing) sink. Notify the registered
+ * listeners.
+ */
+ Recorder.Listener[] listeners;
+
+ synchronized (this.listeners)
+ {
+ listeners
+ = this.listeners.toArray(
+ new Recorder.Listener[this.listeners.size()]);
+ }
+ for (Recorder.Listener listener : listeners)
+ listener.recorderStopped(this);
}
}
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
index 307bab1..2d92cfa 100644
--- a/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
+++ b/src/net/java/sip/communicator/impl/neomedia/device/AudioMixerMediaDevice.java
@@ -206,83 +206,6 @@ public class AudioMixerMediaDevice
}
/**
- * Create a new recording session.
- *
- * @param contentDescriptor the content descriptor for the session.
- * @return a new <tt>MediaDeviceSession</tt>
- */
- public synchronized MediaDeviceSession createRecordingSession(
- final ContentDescriptor contentDescriptor)
- {
- if (deviceSession == null)
- deviceSession = new AudioMixerMediaDeviceSession();
-
- return new MediaStreamMediaDeviceSession(deviceSession)
- {
- /**
- * Starts a specific <tt>Processor</tt> if this
- * <tt>MediaDeviceSession</tt> has been started and the specified
- * <tt>Processor</tt> is not started. Does not check the
- * <tt>MediaDirection</tt> of this session when starting.
- *
- * @param processor the <tt>Processor</tt> to start
- */
- @Override
- protected void startProcessorInAccordWithDirection(
- Processor processor)
- {
- if (processor.getState() != Processor.Started)
- {
- processor.start();
- if (logger.isTraceEnabled())
- {
- logger.trace(
- "Started Processor with hashCode "
- + processor.hashCode());
- }
- }
- }
-
- /**
- * Overrides the method to set the processor's content descriptor
- * to <tt>FileTypeDescriptor.MPEG_AUDIO</tt>.
- *
- * @param event the <tt>ControllerEvent</tt> specifying the
- * <tt>Controller</tt> which is the source of the event and the very
- * type of the event
- */
- @Override
- protected void processorControllerUpdate(ControllerEvent event)
- {
- super.processorControllerUpdate(event);
-
- if (event instanceof ConfigureCompleteEvent)
- {
- Processor processor = (Processor) event.
- getSourceController();
-
- if (processor != null)
- {
- try
- {
- processor.setContentDescriptor(contentDescriptor);
- }
- catch (NotConfiguredError nce)
- {
- logger.error(
- "Failed to set ContentDescriptor to Processor.",
- nce);
- }
-
- if (format != null)
- setProcessorFormat(processor, format);
- }
- }
- }
- };
- }
-
- /**
* Notifies all currently registered <tt>SimpleAudioLevelListener</tt>s
* that our local media now has audio level <tt>level</tt>.
*
diff --git a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java
index 6bdc0d1..06af083 100644
--- a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java
+++ b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java
@@ -71,6 +71,13 @@ public class MediaDeviceSession
private boolean captureDeviceIsConnected;
/**
+ * The <tt>ContentDescriptor</tt> which specifies the content type in which
+ * this <tt>MediaDeviceSession</tt> is to output the media captured by its
+ * <tt>MediaDevice</tt>.
+ */
+ private ContentDescriptor contentDescriptor;
+
+ /**
* The <tt>MediaDevice</tt> used by this instance to capture and play back
* media.
*/
@@ -498,6 +505,27 @@ public class MediaDeviceSession
}
/**
+ * Creates a <tt>ContentDescriptor</tt> to be set on a specific
+ * <tt>Processor</tt> of captured media to be sent to the remote peer.
+ * Allows extenders to override. The default implementation returns
+ * {@link ContentDescriptor#RAW_RTP}.
+ *
+ * @param processor the <tt>Processor</tt> of captured media to be sent to
+ * the remote peer which is to have its <tt>contentDescriptor</tt> set to
+ * the returned <tt>ContentDescriptor</tt>
+ * @return a <tt>ContentDescriptor</tt> to be set on the specified
+ * <tt>processor</tt> of captured media to be sent to the remote peer
+ */
+ protected ContentDescriptor createProcessorContentDescriptor(
+ Processor processor)
+ {
+ return
+ (contentDescriptor == null)
+ ? new ContentDescriptor(ContentDescriptor.RAW_RTP)
+ : contentDescriptor;
+ }
+
+ /**
* Makes sure {@link #captureDevice} is disconnected.
*/
private void disconnectCaptureDevice()
@@ -705,13 +733,13 @@ public class MediaDeviceSession
continue;
Format jmfFormat = trackControl.getFormat();
- MediaType type = jmfFormat instanceof VideoFormat
- ? MediaType.VIDEO : MediaType.AUDIO;
+ MediaType type
+ = (jmfFormat instanceof VideoFormat)
+ ? MediaType.VIDEO
+ : MediaType.AUDIO;
- if(mediaType.equals((type)))
- {
+ if(mediaType.equals(type))
return jmfFormat;
- }
}
}
return null;
@@ -1113,10 +1141,8 @@ public class MediaDeviceSession
{
try
{
- processor
- .setContentDescriptor(
- new ContentDescriptor(
- ContentDescriptor.RAW_RTP));
+ processor.setContentDescriptor(
+ createProcessorContentDescriptor(processor));
}
catch (NotConfiguredError nce)
{
@@ -1220,6 +1246,25 @@ public class MediaDeviceSession
}
/**
+ * Sets the <tt>ContentDescriptor</tt> which specifies the content type in
+ * which this <tt>MediaDeviceSession</tt> is to output the media captured by
+ * its <tt>MediaDevice</tt>. The default content type in which
+ * <tt>MediaDeviceSession</tt> outputs the media captured by its
+ * <tt>MediaDevice</tt> is {@link ContentDescriptor#RAW_RTP}.
+ *
+ * @param contentDescriptor the <tt>ContentDescriptor</tt> which specifies
+ * the content type in which this <tt>MediaDeviceSession</tt> is to output
+ * the media captured by its <tt>MediaDevice</tt>
+ */
+ public void setContentDescriptor(ContentDescriptor contentDescriptor)
+ {
+ if (contentDescriptor == null)
+ throw new NullPointerException("contentDescriptor");
+
+ this.contentDescriptor = contentDescriptor;
+ }
+
+ /**
* Sets the <tt>MediaFormat</tt> in which this <tt>MediaDeviceSession</tt>
* outputs the media captured by its <tt>MediaDevice</tt>.
*
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
index b40c9ce..2b4092b 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -1189,6 +1189,15 @@ public class ProtocolProviderServiceJabberImpl
return connection;
}
+ /**
+ * Determines whether a specific <tt>XMPPException</tt> signals that
+ * attempted authentication has failed.
+ *
+ * @param ex the <tt>XMPPException</tt> which is to be determined whether it
+ * signals that attempted authentication has failed
+ * @return <tt>true</tt> if the specified <tt>ex</tt> signals that attempted
+ * authentication has failed; otherwise, <tt>false</tt>
+ */
private boolean isAuthenticationFailed(XMPPException ex)
{
String exMsg = ex.getMessage().toLowerCase();
@@ -1196,16 +1205,12 @@ public class ProtocolProviderServiceJabberImpl
// as there are no types or reasons for XMPPException
// we try determine the reason according to their message
// all messages that were found in smack 3.1.0 were took in count
- if(exMsg.indexOf("authentication failed") != -1
- || (exMsg.indexOf("authentication") != -1
- && exMsg.indexOf("failed") != -1)
- || exMsg.indexOf("login failed") != -1
- || exMsg.indexOf("unable to determine password") != -1)
- {
- return true;
- }
- else
- return false;
+ return
+ (exMsg.indexOf("authentication failed") != -1)
+ || ((exMsg.indexOf("authentication") != -1)
+ && (exMsg.indexOf("failed") != -1))
+ || (exMsg.indexOf("login failed") != -1)
+ || (exMsg.indexOf("unable to determine password") != -1);
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
index 143d28e..2f30fe5 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetPresenceSipImpl.java
@@ -3176,7 +3176,7 @@ public class OperationSetPresenceSipImpl
/**
* Implements the corresponding <tt>SipListener</tt> method by
- * terminating the corresponding subsctiption and polling the related
+ * terminating the corresponding subscription and polling the related
* contact.
*
* @param requestEvent the event containing the request that was \
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
index 0478c57..7e0fff4 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
@@ -301,7 +301,26 @@ public class ProtocolProviderServiceSipImpl
return this.registeredEvents;
}
-
+ /**
+ * Overrides
+ * {@link AbstractProtocolProviderService#fireRegistrationStateChanged(
+ * RegistrationState, RegistrationState, int, String)} in order to add
+ * enabling/disabling XCAP functionality in accord with the current
+ * <tt>RegistrationState</tt> of this
+ * <tt>ProtocolProviderServiceSipImpl</tt>.
+ *
+ * @param oldState the state that the provider had before the change
+ * occurred
+ * @param newState the state that the provider is currently in
+ * @param reasonCode a value corresponding to one of the REASON_XXX fields
+ * of the <tt>RegistrationStateChangeEvent</tt> class, indicating the reason
+ * for this state transition
+ * @param reason a <tt>String</tt> further explaining the reason code or
+ * <tt>null</tt> if no such explanation is necessary
+ * @see AbstractProtocolProviderService#fireRegistrationStateChanged(
+ * RegistrationState, RegistrationState, int, String)
+ */
+ @Override
public void fireRegistrationStateChanged(RegistrationState oldState,
RegistrationState newState,
int reasonCode,