diff -r 000000000000 -r 094583676ce7 IMPSengine/imapi/src/imclientimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IMPSengine/imapi/src/imclientimpl.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,758 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: mplementation of the IM Client interface (imclient.h) +* +*/ + + + +// INCLUDE FILES +#include "imclientimpl.h" +#include "apiutils.h" +#include "imerrors.h" +#include "imconnectionimpl.h" +#include "cntdbreader.h" + + +// CONSTANTS +const TInt KDetailedListGranularity = 5; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CImClient::CImClient +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CImClient::CImClient( CImConnectionImpl& aImConnection ) + : iImConnection( aImConnection ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Construction" ) ); +#endif + } + +// ----------------------------------------------------------------------------- +// CImClient::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CImClient::ConstructL() + { + } + +// ----------------------------------------------------------------------------- +// CImClient::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CImClient* CImClient::NewL( CImConnectionImpl& aImConnection ) + { + CImClient* self = new( ELeave ) CImClient( aImConnection ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + + +// Destructor +CImClient::~CImClient() + { + +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Destruction" ) ); +#endif + + + // This should be already empty + __ASSERT_DEBUG( iOutstandingOpIds.Count() == 0, + User::Panic( KTxtImOpenApiPanic, EListNotEmpty ) ); + + iOutstandingOpIds.Close(); + + } + + +// ----------------------------------------------------------------------------- +// CImClient::RegisterL +// Starts the registration sequence +// ----------------------------------------------------------------------------- +// +void CImClient::RegisterObserverL( MImObserver* aObserver ) + { + +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: RegisterL" ) ); +#endif + + if ( iClientObserver ) + { + User::Leave( KImApiErrAlreadyRegistered ); + } + + iImClient.RegisterL( + ImpsEngine(), + ImpsImHandler(), + NULL, + iImConnection.ApplicationId(), + ETrue ); + + iImClient.RegisterErrorObserverL( ImpsErrorHandler() ); + + iClientObserver = aObserver; + + } + +// ----------------------------------------------------------------------------- +// CImClient::UnregisterL +// Unregisters the client from the WV engine +// ----------------------------------------------------------------------------- +// +void CImClient::UnregisterObserver() + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: UnregisterL" ) ); +#endif + + // Clear the pointers to the client + iClientObserver = NULL; + + // Unregister from Imps engine + iImClient.Unregister(); + TInt err; + TRAP( err, iImClient.UnregisterErrorObserverL() ); + } + + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const TContactItemId& aContactItem, + const TDesC16& aContent ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Sending PToP text Message (ContactID)" ) ); +#endif + // Check the observer + if ( !iClientObserver ) + { + User::Leave( KImApiErrNotRegistered ); + } + // Get the user IDs from the contact DB + CDesCArraySeg* userIds = new( ELeave ) CDesCArraySeg( 1 ); + CleanupStack::PushL( userIds ); + iImConnection.ContactDBReader().GetWVIdL( aContactItem, *userIds ); + + // check the userIds + if ( userIds->Count() == 0 ) + { + // no valid user to send + CleanupStack::PopAndDestroy(); // >> userIds + User::Leave( KImApiErrInvalidContactId ); + } + +#ifdef _DEBUG + for ( TInt i( 0 ); i < userIds->MdcaCount(); ++i ) + { + TPtrC tmp = ( *userIds )[i]; + CImApiLogger::Log( _L( " User ID: %S" ), &tmp ); + } +#endif + + TInt opId( DoSendMessageL( *userIds, aContent ) ); + CleanupStack::PopAndDestroy(); // >> userIds + return opId; + + } + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const CContactIdArray& aContactIds, + const TDesC16& aContent ) + + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Sending PToP text Message (ContactID)" ) ); +#endif + // Check the observer + if ( !iClientObserver ) + { + User::Leave( KImApiErrNotRegistered ); + } + + // Get the user IDs from the contact DB + CDesCArraySeg* userIds = new( ELeave ) CDesCArraySeg( 1 ); + CleanupStack::PushL( userIds ); + iImConnection.ContactDBReader().ReadWVIdsL( aContactIds, *userIds ); + + // check the userIds + if ( userIds->Count() == 0 ) + { + // no valid user to send + CleanupStack::PopAndDestroy(); // >> userIds + User::Leave( KImApiErrInvalidContactId ); + } + +#ifdef _DEBUG + for ( TInt i( 0 ); i < userIds->MdcaCount(); ++i ) + { + TPtrC tmp = ( *userIds )[i]; + CImApiLogger::Log( _L( " User ID: %S" ), &tmp ); + } +#endif + + TInt opId( DoSendMessageL( *userIds, aContent ) ); + CleanupStack::PopAndDestroy(); // >> userIds + return opId; + + } + + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const TDesC& aUserId, + const TDesC16& aContent ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Sending PToP text Message (UserID)" ) ); + CImApiLogger::Log( _L( " User ID: %S" ), &aUserId ); +#endif + + // Check the observer + if ( !iClientObserver ) + { + User::Leave( KImApiErrNotRegistered ); + } + + // Sanity checking + if ( aUserId.Length() == 0 ) // empty user ID + { + User::Leave( KImApiErrInvalidUserId ); + } + + CDesCArraySeg* userIds = new( ELeave ) CDesCArraySeg( 1 ); + CleanupStack::PushL( userIds ); + userIds->AppendL( aUserId ); + + TInt opId( DoSendMessageL( *userIds, aContent ) ); + CleanupStack::PopAndDestroy(); // >> userIds + return opId; + } + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const MDesCArray& aUserIds, + const TDesC16& aContent ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: Sending PToP text Message (UserID)" ) ); + + for ( TInt i( 0 ); i < aUserIds.MdcaCount(); ++i ) + { + TPtrC tmp = aUserIds.MdcaPoint( i ); + CImApiLogger::Log( _L( " User ID: %S" ), &tmp ); + } +#endif + + // Check the observer + if ( !iClientObserver ) + { + User::Leave( KImApiErrNotRegistered ); + } + + // sanity checking + if ( aUserIds.MdcaCount() == 0 ) // empty list + { + User::Leave( KImApiErrInvalidUserId ); + } + else if ( ( aUserIds.MdcaCount() == 1 ) && + ( aUserIds.MdcaPoint( 0 ).Length() == 0 ) ) // empty user ID + { + User::Leave( KImApiErrInvalidUserId ); + } + + TInt opId( DoSendMessageL( aUserIds, aContent ) ); + return opId; + } + + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const CContactIdArray& /*aContactIds*/, + const TDesC& /*aContentType*/, + const TDesC8& /*aContent*/ ) + { + User::Leave( KErrNotSupported ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CImClient::SendPToPMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::SendPToPMessageL( const MDesCArray& /*aUserIds*/, + const TDesC& /*aContentType*/, + const TDesC8& /*aContent*/ ) + { + User::Leave( KErrNotSupported ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CImClient::HandleNewTextMessageL +// +// ----------------------------------------------------------------------------- +// +void CImClient::HandleNewTextMessageL( TInt /*aOpId*/, + const TDesC& /*aMessageId*/, + const TDesC& aSender, + const TDesC& /*aGroupId*/, + const MDesCArray& /*aRecipients*/, + const MDesCArray& /*aScreenNames*/, + const TDesC& aText, + TImpsCspIdentifier& /*aCspId*/ ) + { +#ifdef _DEBUG + CImApiLogger::Log( + _L( "CImClient: HandleNewTextMessageL" ) ); +#endif + _LIT( KMessageType, "text/plain" ); + + if ( iClientObserver ) + { + iClientObserver->HandleNewPToPMessageL( + KErrNone, + KNullContactId , + aSender, + KMessageType, + aText ); + } + } + +// ----------------------------------------------------------------------------- +// CImClient::HandleSendCompleteL +// +// ----------------------------------------------------------------------------- +// +void CImClient::HandleSendCompleteL( + TInt aOpId, + TBool /*aDeliveryReportOrdered*/, + TImpsCspIdentifier& /*aCspId*/ ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: HandleSendCompleteL" ) ); +#endif + + + RemoveOpId( aOpId ); + + if ( iClientObserver ) + { + iClientObserver->HandleMessageSentL( + aOpId, + KErrNone ); + } + } + + + + +// ----------------------------------------------------------------------------- +// CImClient::HandleNewContentMessageL +// +// ----------------------------------------------------------------------------- +// +void CImClient::HandleNewContentMessageL( + TInt /*aOpId*/, + const TDesC& /*aMessageId*/, + const TDesC& /*aSender*/, + const TDesC& /*aGroupId*/, + const MDesCArray& /*aRecipients*/, + const MDesCArray& /*aScreenNames*/, + const TDesC& /*aContentType*/, + const TDesC8& /*aContent*/, + TImpsCspIdentifier& /*aCspId*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CImClient::HandleDeliveryReportL +// +// ----------------------------------------------------------------------------- +// +void CImClient::HandleDeliveryReportL( + const TDesC& /*aMessageId*/, + TInt /*aResult*/, + const TDesC* /*aDescription*/, + TImpsCspIdentifier& /*aCspId*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CImClient::HandleErrorL +// +// ----------------------------------------------------------------------------- +// +void CImClient::HandleErrorL( TInt aStatus, + TInt aOpId, + const TDesC* /*aDescription*/, + const CImpsDetailed* aDetailedRes, + TImpsCspIdentifier& /*aCspId*/ ) + { +#ifdef _DEBUG + CImApiLogger::Log( _L( "CImClient: IM error received: %d" ), aStatus ); +#endif + + CImClientDetailedErrorImpl* detailedResult = NULL; + + if ( aDetailedRes ) + { + detailedResult = CImClientDetailedErrorImpl::NewL( aDetailedRes ); + CleanupStack::PushL( detailedResult ); // << detailedResult + } + + if ( iClientObserver ) + { + TInt err; + TRAP( err, iClientObserver->HandleSendErrorL( + aOpId, + iImConnection.ConvertImpsEngineErrorCode( aStatus ), + detailedResult ) ); + } + + + // Delete the OpID from the list + RemoveOpId( aOpId ); + if ( detailedResult ) + { + CleanupStack::PopAndDestroy(); // >> detailedResult + } + + } + +// ----------------------------------------------------------------------------- +// CImClient::DoSendMessageL +// +// ----------------------------------------------------------------------------- +// +TInt CImClient::DoSendMessageL( const MDesCArray& aUserIds, + const TDesC& aContent ) + { + + TInt opId( 0 ); + + TRAPD( err, opId = iImClient.SendTextMessageL( NULL, + &aUserIds, + NULL, + NULL, + aContent, + EFalse /*No delivery report*/ ) ); + + if ( err != KErrNone ) + { + // Failed to send + User::Leave ( KImApiGeneralError ); + } + + // Put the OpID to the Outstanding OpIds list + iOutstandingOpIds.Append( opId ); + + return opId; + } + +// ----------------------------------------------------------------------------- +// CImClient::RemoveOpId +// +// ----------------------------------------------------------------------------- +// +void CImClient::RemoveOpId( TInt aOpId ) + { + TInt index = iOutstandingOpIds.Find( aOpId ); + + // OpID is not found from the list there is a problem somewhere + __ASSERT_DEBUG( ( index != KErrNotFound ), + User::Panic( KTxtImOpenApiPanic, EListCorrupted ) ); + + iOutstandingOpIds.Remove( index ); + } + + +// ----------------------------------------------------------------------------- +// CImClient::ImpsImHandler +// +// ----------------------------------------------------------------------------- +// +MImpsImHandler2* CImClient::ImpsImHandler() + { + return this; + } + +// ----------------------------------------------------------------------------- +// CImClient::ImpsErrorHandler +// +// ----------------------------------------------------------------------------- +// +MImpsErrorHandler2& CImClient::ImpsErrorHandler() + { + return *this; + } + +// ----------------------------------------------------------------------------- +// CImClient::ImpsEngine +// +// ----------------------------------------------------------------------------- +// +RImpsEng& CImClient::ImpsEngine() + { + return iImConnection.ImpsEngine(); + } + + +// ----------------------------------------------------------------------------- +// CImClient::ClientObserver +// +// ----------------------------------------------------------------------------- +// +MImObserver* CImClient::ClientObserver() + { + return iClientObserver; + } + + +////////////////////////////////////////////////////////////////////////// +// TDetailedResultItem + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::TDetailedResultItem +// +// ----------------------------------------------------------------------------- +// +TDetailedResultItem::TDetailedResultItem() + { + } + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::TDetailedResultItem +// +// ----------------------------------------------------------------------------- +// +TDetailedResultItem::~TDetailedResultItem() + { + } + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::SetErrorCode +// +// ----------------------------------------------------------------------------- +// +void TDetailedResultItem::SetErrorCode( TInt aErroCode ) + { + iErrorCode = aErroCode; + } + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::ErrorCode +// +// ----------------------------------------------------------------------------- +// +TInt TDetailedResultItem::ErrorCode() const + { + return iErrorCode; + } + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::SetUserId +// +// ----------------------------------------------------------------------------- +// +void TDetailedResultItem::SetUserId( TDesC& aUserId ) + { + iUserId.Set( aUserId ); + } + +// ----------------------------------------------------------------------------- +// TDetailedResultItem::UserId +// +// ----------------------------------------------------------------------------- +// +const TDesC& TDetailedResultItem::UserId() const + { + return iUserId; + } + + +////////////////////////////////////////////////////////////////////////// +// CImClientDetailedErrorImpl +////////////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::CImClientDetailedErrorImpl +// +// ----------------------------------------------------------------------------- +// +CImClientDetailedErrorImpl::CImClientDetailedErrorImpl() + { + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::CImClientDetailedErrorImpl +// +// ----------------------------------------------------------------------------- +// +void CImClientDetailedErrorImpl::ConstructL( + const CImpsDetailed* aImpsDetailed ) + { + iDetailedList = new( ELeave ) CArrayFixFlat( + KDetailedListGranularity ); + DoInitL( aImpsDetailed ); + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::CImClientDetailedErrorImpl +// +// ----------------------------------------------------------------------------- +// +CImClientDetailedErrorImpl* CImClientDetailedErrorImpl::NewL( + const CImpsDetailed* aImpsDetailed ) + { + CImClientDetailedErrorImpl* self = new( ELeave ) CImClientDetailedErrorImpl(); + CleanupStack::PushL( self ); + self->ConstructL( aImpsDetailed ); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::~CImClientDetailedErrorImpl +// +// ----------------------------------------------------------------------------- +// +CImClientDetailedErrorImpl::~CImClientDetailedErrorImpl() + { + delete iDetailedList; + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::Count +// +// ----------------------------------------------------------------------------- +// +TInt CImClientDetailedErrorImpl::Count() + { + return iDetailedList->Count(); + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::UserId +// +// ----------------------------------------------------------------------------- +// +const TDesC& CImClientDetailedErrorImpl::UserId( TInt aIndex ) + { + // out-of-bounds will panic: E32USER-CBase 21 + return iDetailedList->At( aIndex ).UserId(); + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::ErrorCode +// +// ----------------------------------------------------------------------------- +// +TInt CImClientDetailedErrorImpl::ErrorCode( TInt aIndex ) + { + // out-of-bounds will panic: E32USER-CBase 21 + return iDetailedList->At( aIndex ).ErrorCode(); + } + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::DoInitL +// Initializes the detailed list from the ImpsDetailed +// ----------------------------------------------------------------------------- +// +void CImClientDetailedErrorImpl::DoInitL( const CImpsDetailed* aImpsDetailed ) + { + TInt detailedCount = aImpsDetailed->Count(); + for ( TInt i( 0 ); i < detailedCount; ++i ) + { + // Get all the failed user IDs + // and make a list of those IDs + CPtrC16Array* userIds = aImpsDetailed->At( i )->UserIds(); + if ( userIds ) + { + TInt userCount = userIds->Count(); + for ( TInt j( 0 ); j < userCount; ++j ) + { + TDetailedResultItem resultItem; + resultItem.SetUserId( userIds->At( j ) ); + resultItem.SetErrorCode( ConvertWVErrorCode( + aImpsDetailed->At( i )->Code() ) ); + iDetailedList->AppendL( resultItem ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// CImClientDetailedErrorImpl::ConvertWVErrorCode +// Converts the WV error code to an API error code +// ----------------------------------------------------------------------------- +// +TInt CImClientDetailedErrorImpl::ConvertWVErrorCode( TInt aErrorCode ) + { + // Do not try to convert KErrNone + if ( aErrorCode == KErrNone ) + { + return KErrNone; + } + + TInt returnValue; + switch ( aErrorCode ) + { + case 531: // Recipient does not exist + returnValue = KImApiErrInvalidUserId; + break; + case 532: //Recipient user blocked the sender + returnValue = KImApiErrSenderBlocked; + break; + + case 533: // Recipient user is not logged in + returnValue = KImApiErrRecipientNotLogged; + break; + + default: + returnValue = KImApiGeneralError; + break; + + } + return returnValue; + } +// End of File