IMPSengine/imapi/src/imclientimpl.cpp
changeset 0 094583676ce7
--- /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<TDetailedResultItem>(
+        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