messagingfw/deprecate/senduiservices/src_old/SendUiImpl.cpp
branchRCL_3
changeset 22 d2c4c66342f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/deprecate/senduiservices/src_old/SendUiImpl.cpp	Tue Aug 31 15:41:11 2010 +0300
@@ -0,0 +1,1256 @@
+/*
+* Copyright (c) 2002-2006 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:   Can be used to show "Send" list query and to create and send
+*                messages via available sending services. Created messages are
+*                sent directly or message editor is opened for editing,
+*                depending on the type of the selected service.
+*
+*/
+
+
+#include <coemain.h>
+#include <Sendnorm.rsg>
+#include <AknListQueryDialog.h>
+#include <eikmenup.h>
+#include <data_caging_path_literals.hrh>
+#include <DRMHelper.h>
+#include <centralrepository.h>
+#include <e32cmn.h> // Uid
+#include <e32property.h>
+#include <barsread.h>
+#include <akninputblock.h>
+#include <centralrepository.h>
+#include <miutset.h>
+#include <MessagingDomainCRKeys.h>
+
+// Features
+#include <FeatMgr.h>    
+#include <bldvariant.hrh>
+#include <msgmimetypes.h>
+#include <CSendingServiceInfo.h>
+#include <CSendingService.h>
+#include <CMessageData.h>
+#include <SendUiConsts.h>
+#include <senduisingleton.h>
+
+#include "SendUiImpl.h"
+#include "senduiserviceclient.h"
+#include "SendUiCapabilityCheck.h"
+#include "SendUiUtils.h"
+#include "senduiserviceslog.h"              // Logging
+#include "SendUiPrivateCRKeys.h"
+#include "senduiproperty.h"
+#include "propertyobserver.h"
+#include "senduilauncher.h"
+#include "SendUiInternalConsts.h"
+
+
+const TInt KArrayGranularity = 2;
+const TInt KSendUiServiceOrderArrayGranularity = 6;
+const TInt KTitleBufLength = 64;
+
+
+_LIT( KSendUiResourceFileName,"sendnorm.rsc" );
+
+// ======== MEMBER FUNCTIONS ========
+// -----------------------------------------------------------------------------
+// CSendUiImpl::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CSendUiImpl* CSendUiImpl::NewL()
+    {
+    CSendUiImpl* self = new( ELeave ) CSendUiImpl;
+    
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CSendUiImpl::~CSendUiImpl()
+    {
+    iResourceLoader.Close();
+    TInt count = iSendingServices.Count();
+    while ( count )
+        {
+        delete iSendingServices[--count];
+        }
+    iSendingServices.Close();
+    delete iSendUiServicesOrderArray;
+    delete iServicesToDim;
+    delete iPropertyObserver;
+    delete iSingleton;
+    }
+
+// -----------------------------------------------------------------------------
+// AddTypedMenuItemL
+//
+// No menu item is added, if services are not found. This can happen if asyncronous
+// sending service update is not yet finished.
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::AddTypedMenuItemL(
+    CSendUi::TSendUiMenuType    aMenuType,
+    CEikMenuPane&               aMenuPane,
+    TInt                        aIndex,
+    TInt                        aCommandId,
+    TSendingCapabilities        aRequiredCapabilities )
+    {
+    TInt i(0);
+    TBool menuItemAdded = EFalse;
+    TBuf<KTitleBufLength> menuItemName;
+    
+     // Read the resources
+    aMenuType == CSendUi::ESendMenu ? 
+        i = R_SENDUI_MENUITEM_SEND : 
+        i = R_SENDUI_MENUITEM_WRITE; // CSendUi::EWriteMenu
+        
+    iCoeEnv->ReadResourceL( menuItemName, i );
+  
+    for ( i = 0; i < iSendingServices.Count(); i++ )
+    {
+    TUid serviceUid = iSendingServices[i]->ServiceId();
+    if ( QueryCapabilities( i, aRequiredCapabilities ) )
+        {
+        CEikMenuPaneItem::SData data;
+        data.iCascadeId = NULL;
+        data.iText = menuItemName;
+        data.iCommandId = aCommandId;
+
+        if ( aIndex == aMenuPane.NumberOfItemsInPane() )
+            {
+            aMenuPane.AddMenuItemL( data );
+            }
+        else
+            {
+            aMenuPane.InsertMenuItemL( data, aIndex );
+            }
+            
+        menuItemAdded = ETrue;
+        break;
+        }
+    }
+
+    // Hide menu item if sending is already in progress.
+    if ( menuItemAdded )
+        {
+        aMenuPane.SetItemDimmed( aCommandId, iIsSending);
+        }        
+    }
+
+// -----------------------------------------------------------------------------
+// ShowTypedQueryAndSendL
+// First shows list query and then creates the message.
+// Editor is launched for editing the message or the message is sent
+// directly without opening the editor. Functionality depends on the
+// type of selected sending service.
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::ShowTypedQueryAndSendL(
+    CSendUi::TSendUiMenuType    aMenuType,
+    const CMessageData*         aMessageData,
+    TSendingCapabilities        aRequiredCapabilities,
+    CArrayFix<TUid>*            aServicesToDim,
+    TBool                       aLaunchEditorEmbedded,
+    const TDesC&                aTitleText )
+    {
+    TUid serviceId = ShowTypedQueryL(
+        aMenuType,
+        aMessageData,
+        aRequiredCapabilities,
+        aServicesToDim,
+        aTitleText );
+
+    if ( serviceId != KNullUid )
+        {
+        // Process user selection.
+        CreateAndSendMessageL(
+            serviceId,
+            aMessageData,
+            aLaunchEditorEmbedded);
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// ShowTypedQueryL
+// Shows list query and returns the user selection.
+// -----------------------------------------------------------------------------
+//
+TUid CSendUiImpl::ShowTypedQueryL(
+    CSendUi::TSendUiMenuType    aMenuType,
+    const CMessageData*         aMessageData,
+    TSendingCapabilities        aRequiredCapabilities,
+    CArrayFix<TUid>*            aServicesToDim,
+    const TDesC&                aTitleText )
+    {
+    // Implemented for CR # 401-1806 >>    
+    // This section to enable/disable features (supported by feature manager) at run time, is to be revised,
+    // once an observer class is available from feature manager side to intimate about feature state
+		
+    CRepository* repository = CRepository::NewLC( KCRUidSendUi );
+    TInt oldFeatures(0);   
+    TInt newFeatures(0); 
+    TBool updateNeeded( EFalse );   
+    
+    if ( repository->Get( KKeySendUiFeatureManagerServices, oldFeatures ) != KErrNone )
+    	{
+    	updateNeeded = ETrue;
+    	}
+    FeatureManager::InitializeLibL();
+    FeatureStatus( KFeatureIdMmsPostcard, newFeatures, KSendUiPostcard );
+    FeatureStatus( KFeatureIdAudioMessaging, newFeatures, KSendUiAudioMessage );
+    FeatureStatus( KFeatureIdSenduiMmsUpload, newFeatures, KSendUiMmsUpload );
+    FeatureManager::UnInitializeLib();
+    if ( newFeatures != oldFeatures )
+        {
+        repository->Set( KKeySendUiFeatureManagerServices, newFeatures );
+        updateNeeded = ETrue;
+        }
+
+    CleanupStack::PopAndDestroy( repository );
+    
+    RProperty propertyUpdateOperation;
+    TRequestStatus status;
+    if ( updateNeeded )
+        {
+        RProperty::Set( 
+            KPSUidSendUiProperty, 
+            KSendUiUpdateRequest, 
+            KSendUiUpdateRequested );
+        User::LeaveIfError( propertyUpdateOperation.Attach( KPSUidSendUiProperty, KSendUiUpdateRequest ));
+        propertyUpdateOperation.Subscribe( status );	
+        User::WaitForRequest(status);
+        TInt value = KErrNone;
+        if(propertyUpdateOperation.Get( value ) !=KErrNotFound && value == KSendUiUpdated )
+            {
+            TRAPD( err, GetServicesL() );
+            if ( err )
+                {
+#ifdef _DEBUG
+                TBuf<256> buf;
+                buf.Format(_L("SendUi err"));
+                User::InfoPrint(buf);
+#endif
+                TUid serviceId( KNullUid );
+                return serviceId;
+                }
+            }
+        propertyUpdateOperation.Close();
+        }
+    // Implemented for CR # 401-1806 <<    
+    // List items for list query.
+    CDesCArrayFlat* listItems = new (ELeave) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( listItems);
+
+    // This array is used to map user selection to correct service.
+    CArrayFix<TUid>* listItemUids = 
+        new ( ELeave ) CArrayFixFlat<TUid>( KArrayGranularity );
+    CleanupStack::PushL( listItemUids );
+
+    iServicesToDim->Reset();
+
+    TInt i = 0;
+    if ( aServicesToDim )
+        {
+        for ( i = 0; i < aServicesToDim->Count(); i++  )
+            {
+            iServicesToDim->AppendL( (*aServicesToDim)[i] );
+            }
+        }
+  
+    // Get and filter ECom based services.
+    FilterServicesL(
+        *listItems,
+        *listItemUids,
+        aRequiredCapabilities,
+        aMessageData,
+        aMenuType );
+
+    TUid serviceId( KNullUid );
+    if ( listItems->Count() > 0 )
+        {
+        // Show list query.
+        SortListL( *listItems, *listItemUids );
+
+        serviceId = ShowListQueryL(
+            listItems,
+            *listItemUids,
+            aTitleText,
+            aMenuType );
+        }
+
+    CleanupStack::PopAndDestroy( 2, listItems );  // listItemUids, listItems
+
+    return serviceId;
+    }
+
+// -----------------------------------------------------------------------------
+// SendMessageL
+// -----------------------------------------------------------------------------
+TInt CSendUiImpl::SendMessageL(    
+    TUid                    aServiceUid,
+    const CMessageData*     aMessageData,
+    TBool                   aLaunchEditorEmbedded)
+    { 
+    if ( iIsSending || aServiceUid == KNullUid )
+        {
+        return KErrNone;
+        }
+        
+        CAknInputBlock* absorber = CAknInputBlock::NewLC( ); 
+        // Ensures proper sending state if leave happens.
+        iIsSending = ETrue;
+        TInt success( KErrNone );
+        CleanupStack::PushL( TCleanupItem( ResetIsSending, (TAny*)&iIsSending ) );
+
+        // Create the requested ECom service.
+        TInt i( ResolveServiceIndex( aServiceUid ));
+        if ( i != KErrNotFound )
+            {
+            TRAP( success, 
+                CSendingService* sendingService = CSendingService::NewL( 
+                    iSendingServices[i]->ServiceProviderId(), *iCoeEnv, *iSingleton );
+                CleanupStack::PushL( sendingService );  
+                
+                sendingService->CreateAndSendMessageL( aServiceUid, aMessageData, aLaunchEditorEmbedded );
+                CleanupStack::PopAndDestroy( sendingService );
+                    );
+                
+            }
+        else
+            {
+            iIsSending = EFalse;
+            }
+    CleanupStack::PopAndDestroy( 2, absorber); // TCleanupItem, absorber
+    return success;
+    }
+
+// -----------------------------------------------------------------------------
+// SendMessageViaServer
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::SendMessageViaServerL( 
+    TUid                    aServiceUid,
+    const CMessageData*     aMessageData,
+    TBool                   aLaunchEditorEmbedded )
+    {
+    TInt index( ResolveServiceIndex( aServiceUid ));
+    TBool capabilitiesOk = ETrue;
+    if ( index == KErrNotFound )
+    	{
+    	return;
+    	}
+    if ( iSendingServices[index]->ServiceFeatures() & CSendingServiceInfo::EServiceCanSendDirectly )
+    	{
+	    // Check sending rights
+	    RProcess process;
+	    TSecurityInfo securityInfo( process );
+	    CSendUiCapabilityCheck* capabilityCheck = CSendUiCapabilityCheck::NewLC();
+
+		capabilitiesOk = capabilityCheck->CheckCapabilitiesL( 
+		    securityInfo, 
+		    iSingleton->MsvSessionL(), 
+		    KSenduiMtmMmsUid, 
+		    iSendingServices[index]->ServiceName() );
+		    
+		CleanupStack::PopAndDestroy( capabilityCheck );
+	    }
+    
+    if ( capabilitiesOk )
+    	{
+        TUid providerUid = iSendingServices[index]->ServiceProviderId();	
+	    RSendUiServiceClient sendUiClient;
+	    CleanupClosePushL( sendUiClient );
+	    sendUiClient.ConnectChainedAppL( KSendUiLauncherAppUid );
+	    // LaunchSendUiL is syncronous operation
+	    sendUiClient.LaunchSendUiL( 
+	        aServiceUid,
+	        providerUid,
+	        aLaunchEditorEmbedded, 
+	        aMessageData ); 
+	    CleanupStack::PopAndDestroy( &sendUiClient);
+    	}
+	    
+    }
+
+// -----------------------------------------------------------------------------
+// CreateAndSendMessageL
+// Creates the message and launches the editor for editing the message
+// or sends the message directly without opening the editor. 
+// Functionality depends on the type of selected sending service.
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::CreateAndSendMessageL(
+    TUid                    aServiceUid,
+    const CMessageData*     aMessageData,
+    TBool                   aLaunchEditorEmbedded )
+    {
+    LOGTEXT(_L("CSendUiImpl::CreateAndSendMessageL >>"));
+    TInt err(0); // initializing this to 0 helps debugging SendMessageViaServerL
+    err = SendMessageL( aServiceUid, aMessageData, aLaunchEditorEmbedded );
+    if ( !iServerAppLaunch && ( err == KErrPermissionDenied || err == KErrAccessDenied ) )
+        {
+        SendMessageViaServerL( aServiceUid, aMessageData, aLaunchEditorEmbedded );
+        }
+    else
+       	{
+        User::LeaveIfError( err );
+       	}
+    LOGTEXT(_L("CSendUiImpl::CreateAndSendMessageL <<"));
+   }
+
+// -----------------------------------------------------------------------------
+// ServiceCapabilitiesL
+// Returns sending capabilities of the sending service.
+// -----------------------------------------------------------------------------
+//
+TInt CSendUiImpl::ServiceCapabilities(
+    TUid                    aServiceUid,
+    TSendingCapabilities&   aServiceCapabilities )
+    {
+    TInt i( ResolveServiceIndex( aServiceUid ));
+    
+    if ( i != KErrNotFound )
+        {
+        aServiceCapabilities = 
+            iSendingServices[i]->ServiceCapabilities();
+        i = KErrNone;        
+        }
+    return i;
+    }
+
+// -----------------------------------------------------------------------------
+// AvailableServicesL
+// Populates given list with the information about services
+// provided by specified ECom service provider.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+
+void CSendUiImpl::AvailableServicesL(
+    RPointerArray<CSendingServiceInfo>& aServiceList,
+    TUid aServiceProvider)
+    {
+    for ( TInt i(0); i < iSendingServices.Count(); i++ )
+        {
+        if ( iSendingServices[i]->ServiceProviderId() == aServiceProvider 
+            || aServiceProvider == KNullUid )
+            {
+            CSendingServiceInfo* serviceInfo = iSendingServices[i]->CopyLC();
+            aServiceList.AppendL( serviceInfo );
+            CleanupStack::Pop( serviceInfo ); // serviceInfo
+            }
+        }
+    }
+// -----------------------------------------------------------------------------
+// TechnologyType
+// -----------------------------------------------------------------------------
+//
+TUid CSendUiImpl::TechnologyType( TUid aServiceUid )
+    {
+    TInt i = ResolveServiceIndex( aServiceUid );
+    if ( i != KErrNotFound )
+        {
+        return iSendingServices[i]->TechnologyTypeId(); 
+        }
+    else
+        {        
+        return TUid::Null();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CSendUiImpl::ResolveServiceIndex( TUid aServiceUid )
+    {
+    TInt index( iSendingServices.Count() );
+    
+    while( --index >= 0)
+        {
+        if ( iSendingServices[index]->ServiceId() == aServiceUid )
+            {
+            return index;           
+            }
+        }
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// QueryCapabilities
+// -----------------------------------------------------------------------------
+//
+TBool CSendUiImpl::QueryCapabilities( 
+    TInt index, 
+    TSendingCapabilities aRequiredCapabilities )
+    {
+    if ( index == KErrNotFound )
+    	{
+    	return EFalse;
+    	}
+
+     if ( aRequiredCapabilities.iFlags == TSendingCapabilities::EAllServices )
+        { 
+        // No capabilities required from service
+        return ETrue;
+        }
+    TSendingCapabilities serviceCap = iSendingServices[ index ]->ServiceCapabilities();
+    
+    if ( !(serviceCap.iMessageSize == 0 // no size limit set for the service
+    || aRequiredCapabilities.iMessageSize == 0 ) // no size limit asked from the client
+    && aRequiredCapabilities.iMessageSize > serviceCap.iMessageSize )
+        {
+        return EFalse;
+        }
+    
+    // Check if support for attachments are required.
+    if ( aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsAttachments
+        && serviceCap.iFlags & TSendingCapabilities::ESupportsAttachments )
+        {
+        return ETrue;
+        }
+
+    // Check if support for body text is required.
+    if ( aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsBodyText )
+        {
+        if ( serviceCap.iFlags & TSendingCapabilities::ESupportsBodyText )
+            {
+            if ( serviceCap.iBodySize > 0 && aRequiredCapabilities.iBodySize > serviceCap.iBodySize )
+                {
+                return EFalse; // size limit defined and it is enough
+                }
+            // no size limit in service for bodytext or required size below max size.
+            return ETrue;
+            }
+        }
+        
+    
+    // Check if support for BIO sending is required.
+        if ( aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsBioSending 
+             && serviceCap.iFlags & TSendingCapabilities::ESupportsBioSending )
+            {
+            return ETrue;
+            }
+
+    // Check if support for editor is required.
+        if ( aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsEditor
+             && serviceCap.iFlags & TSendingCapabilities::ESupportsEditor )
+            {
+            return ETrue;
+            }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CSendUiImpl::GetServicesL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+
+void CSendUiImpl::GetServicesL( )
+{
+    TInt value(0);
+    TInt serviceCount;
+    TInt cleanupItems(0);
+    
+    CRepository* rep = CRepository::NewLC( KCRUidSendUi );
+    cleanupItems++;
+    TInt err = rep->Get( KKeySendUiServiceCount, serviceCount );
+    
+    if ( err )
+        {
+        LOGTEXT(_L("SendUiImpl->GetServicesL: Cenrep init file missing"));
+        CleanupStack::PopAndDestroy( rep );
+        return;
+        }
+    else
+        {
+        if ( serviceCount == KSendUiNotInitialized )
+            {
+            // Services has not been initialized, launch service resolver in the bacground.
+            CleanupStack::PopAndDestroy( rep);
+            // iSendingServices are updated, when update is done.
+            RProperty::Set( 
+                KPSUidSendUiProperty, 
+                KSendUiUpdateRequest, 
+                KSendUiUpdateRequested); 
+
+            return;            
+            }
+        }
+    
+    while ( iSendingServices.Count() )
+        {
+        delete iSendingServices[0];
+        iSendingServices.Remove(0);
+        }
+        
+    HBufC* text = HBufC::NewLC( KSendUiServiceMaxNameLength );
+    cleanupItems++;
+    TPtr ptr = text->Des();
+    TInt key;
+    for( TInt i(0); i < serviceCount; i++ )
+        {
+        key = KSendUiServiceIndex * i;
+        CSendingServiceInfo* info = CSendingServiceInfo::NewLC();
+    
+        err = rep->Get( key | KSendUiServiceId, value );
+        if (!err )
+            {
+            info->SetServiceId( TUid::Uid( value  ));
+            }
+
+        err = rep->Get( key | KSendUiServiceProviderId, value );
+        if (!err )
+            {
+            info->SetServiceProviderId( TUid::Uid( value  ));
+            }
+
+       err = rep->Get( key | KSendUiServiceName, ptr );
+        if (!err)
+            {
+            __ASSERT_DEBUG( ptr.Length() <= KSendUiServiceMaxNameLength, User::Invariant() );
+            info->SetServiceNameL( ptr );
+            }
+        
+        err = rep->Get( key | KSendUiServiceMenuName, ptr );
+        if (!err)
+            {
+            __ASSERT_DEBUG( ptr.Length() <= KSendUiServiceMaxNameLength, User::Invariant() );
+            info->SetServiceMenuNameL( ptr );
+            }
+        
+        err = rep->Get( key | KSendUiServiceAddress, ptr );
+        if (!err)
+            {
+            __ASSERT_DEBUG( ptr.Length() <= KSendUiServiceMaxNameLength, User::Invariant() );
+            info->SetServiceAddressL( ptr );
+            }
+        
+        TSendingCapabilities cap;
+            
+        err = rep->Get( key | KSendUiServiceFlags, value );
+        if (!err)
+            {
+            cap.iFlags = value;
+            }
+        
+        err = rep->Get( key | KSendUiServiceBodySize, value );
+        if (!err)
+            {
+            cap.iBodySize = value;
+            }
+        
+        err = rep->Get( key | KSendUiServiceMessageSize, value );
+        if (!err)
+            {
+            cap.iMessageSize = value;
+            }
+    
+    
+        err = rep->Get( key | KSendUiServiceTechnologyType, value );
+        if (!err )
+            {
+            info->SetTechnologyTypeId( TUid::Uid( value  ));
+            }
+        
+        err = rep->Get( key | KSendUiServiceFeatures, value );
+        if (!err)
+            {
+            info->SetServiceFeatures( value );
+            }
+    
+        if (!err)
+            {
+            info->SetServiceCapabilities( cap );            
+            iSendingServices.Append( info );
+            CleanupStack::Pop( info);
+            }
+
+        }
+    
+    CleanupStack::PopAndDestroy( cleanupItems, rep); // text, rep
+    
+}
+
+// ---------------------------------------------------------
+// ShowListQueryL(
+// Displays list query.
+// (other items were commented in a header).
+// ---------------------------------------------------------
+// 
+TUid CSendUiImpl::ShowListQueryL(
+    MDesCArray*                 aListItems,
+    const CArrayFix<TUid>&      aListItemUids,
+    const TDesC&                aTitleText,
+    CSendUi::TSendUiMenuType    aMenuType )
+    {
+    // Show list query.
+    TInt choice = KErrNotFound;
+    CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog( &choice );
+    TInt ret = 0;
+    TRAPD( err, 
+    dlg->PrepareLC( R_SENDUI_LIST_QUERY );
+    dlg->SetItemTextArray( aListItems );
+    dlg->SetOwnershipType( ELbmDoesNotOwnItemArray );
+
+    // Set title
+    CAknPopupHeadingPane* heading = dlg->Heading();
+
+    if ( aTitleText != KNullDesC )
+        {
+        heading->SetTextL( aTitleText );
+        }
+    else 
+        {
+        HBufC* title;
+        TInt titleId(0);
+        if (aMenuType == CSendUi::ESendMenu )
+            {
+            titleId = R_SENDUI_LIST_QUERY_TITLE ;
+            }
+        else if ( aMenuType == CSendUi::EWriteMenu )
+            {
+            titleId = R_SENDUI_LIST_QUERY_TITLE_WRITE;
+            }
+        
+        if ( titleId )
+            {
+            title = iCoeEnv->AllocReadResourceLC( titleId );
+            heading->SetTextL( *title );
+            CleanupStack::PopAndDestroy( title );
+            }
+        }
+    
+    ret = dlg->RunLD();
+    ); //end of TRAPD
+    
+    if( err == KLeaveExit )
+        {
+        delete dlg;
+        dlg = NULL;
+        }
+    
+    if ( !ret )
+        {
+        return KNullUid;
+        }
+    return aListItemUids.At( choice );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CanSendContentL
+// -----------------------------------------------------------------------------
+//
+TBool CSendUiImpl::CanSendContentL(
+    TUid                    aServiceUid,
+    TUid                    aServiceProviderId,
+    const CMessageData*     aMessageData,
+    TDataType*              aMimeType )
+    {
+    // Other ecoms are filtered by their base provider, but versitile MTMs under 
+    // GenericMtmPlugin have filtering by their serviceUid    
+    if ( aServiceProviderId != KGenericMtmPlugin )
+    {
+        aServiceUid = aServiceProviderId;
+    }
+    // Content based filtering is done only for some selected services.
+    // Cannot filter with no data, certain services and audio message (if no audiomessage support)
+    if ( !aMessageData ||
+         !( aServiceUid == KDrmLinkSender || 
+            aServiceUid == KSenduiMtmPostcardUid ||
+            aServiceUid == KMmsDirectUpload ||
+            aServiceUid == KMmsIndirectUpload ||
+            aServiceUid == KSenduiMtmAudioMessageUid ||
+            aServiceUid == KSenduiMtmSmsUid ) )                            
+        {
+        return ETrue;
+        }
+
+
+    const CDesCArray& attachmentPaths = aMessageData->AttachmentArray();
+    const RArray<RFile>& attachments = aMessageData->AttachmentHandleArray();
+
+    TInt attachmentCount = attachmentPaths.Count() + attachments.Count();
+
+    if ( attachmentCount == 0 )
+        { // No content to send
+        
+        if ( aServiceUid == KDrmLinkSender )
+            {
+            return EFalse;
+            }
+        TInt bodyTextLength = aMessageData->BodyText()->DocumentLength();
+        // Dim MMS Upload services, if there is no bodytext
+        if ( ( aServiceUid == KMmsDirectUpload 
+            || aServiceUid == KMmsIndirectUpload ) 
+            && bodyTextLength == 0 )
+            {
+            return EFalse; // bodytext will be converted into attachment
+            }
+        // Dim Audio message, if there is bodytext    
+        if ( aServiceUid == KSenduiMtmAudioMessageUid 
+            && bodyTextLength > 0 )
+            {
+            return EFalse;
+            }
+        return ETrue;
+        }
+    else if ( attachmentCount == 1  )
+        {
+        TBool result = ETrue;
+        
+        switch ( aServiceUid.iUid )
+            {
+            case KSenduiMtmSmsUidValue: 
+                {
+                if ( aMimeType->Des8().CompareF( KMsgMimeVCard ) != 0 &&
+                     aMimeType->Des8().CompareF( KMsgMimeVCal ) != 0 )
+                    {
+                    result = EFalse;
+                    }
+                break;
+                }
+            case KSenduiMtmPostcardUidValue:
+                {
+                if( aMimeType->Des8().CompareF( KMsgMimeImageJpeg ) != 0 &&
+                    aMimeType->Des8().CompareF( KMsgMimeImageGif ) != 0 &&
+                    aMimeType->Des8().CompareF( KMsgMimeImagePng ) != 0 &&
+                    aMimeType->Des8().CompareF( KMsgMimeTextPlain ) != 0 )
+                    {
+                    // Supported types: jpeg, png, gif, plain text
+                    result = EFalse;
+                    }
+                }
+                break;   
+            case KSenduiMtmAudioMessageUidValue:
+                {
+                if( aMimeType->Des8().CompareF( KMsgMimeAudioAmr ) != 0 ||
+                    aMessageData->BodyText()->DocumentLength() > 0 )
+                    {
+                    // Does not allow other than amr attachment and empty bodytext
+                    result = EFalse;
+                    }
+                }    
+                break;    
+            case KDrmLinkSenderValue:
+                {
+                // Check OMA DRM level
+
+                TInt drmMethod = 0;
+                CDRMHelper::TDRMHelperOMALevel omaDRMLevel;
+                CDRMHelper* drmHelper = NULL;
+                TRAPD( error, drmHelper = CDRMHelper::NewL( iFs ) );
+                if ( error != KErrNone )
+                    {
+                    return error;
+                    }
+                error = drmHelper->SupportedDRMMethods2( drmMethod, omaDRMLevel );
+                if ( !(omaDRMLevel & CDRMHelper::EOMA_2_0 ))
+                     {
+                     result = EFalse;
+                     break;
+                     }
+                delete drmHelper;
+
+
+                if ( attachmentPaths.Count() )
+                    {
+                    RFile handle = SendUiUtils::OpenFileHandleL( attachmentPaths.MdcaPoint(0), iFs );
+                    CleanupClosePushL( handle );
+                    result = SendUiUtils::HasContentUrlL( handle );
+                    CleanupStack::PopAndDestroy( &handle );
+                    }
+                else
+                    {
+                    result = SendUiUtils::HasContentUrlL( const_cast<RFile&>( attachments[0] ) );
+                    }
+                }
+                break;
+            default:
+                // Should never end up here
+                break;
+            }
+     
+        return result;        
+        }
+    else if ( attachmentCount > 1  )
+        {
+        if ( aServiceUid == KDrmLinkSender ||
+             aServiceUid == KSenduiMtmPostcardUid ||
+             aServiceUid == KSenduiMtmAudioMessageUid ||
+             aServiceUid == KSenduiMtmSmsUid )
+            {
+            // Currently supports sending of one file only
+            // or no files (SMS)
+            return EFalse;
+            }
+        return ETrue;
+        }
+   
+   // Should never end up here
+   return ETrue;
+   }
+
+// -----------------------------------------------------------------------------
+// CSendUiImpl::FilterServicesL
+// 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::FilterServicesL(
+    CDesCArrayFlat&         aListItems,
+    CArrayFix<TUid>&        aListItemUids,
+    TSendingCapabilities    aRequiredCapabilities,
+    const CMessageData*     aMessageData,
+    CSendUi::TSendUiMenuType    aMenuType  )
+    {
+    TInt i = 0;
+    TInt cc = 0;
+    TBool dimService = EFalse;
+	TDataType* mimeType = NULL;
+	TInt cleanupItems(0);
+    // Filter some services away if there is no content to be send.
+    if ( !aMessageData )
+        {
+        iServicesToDim->AppendL( KDrmLinkSender );
+        iServicesToDim->AppendL( KMmsDirectUpload );
+        iServicesToDim->AppendL( KMmsIndirectUpload );
+        iServicesToDim->AppendL( KShareOnline );
+        }
+    else if ( aMessageData->AttachmentArray().Count() == 1
+            || aMessageData->AttachmentHandleArray().Count() == 1 )
+    	{
+    	// CanSendContent can recycle these in mime type resolving
+    	// for all services that have attachments
+		mimeType = new (ELeave) TDataType();
+		CleanupStack::PushL( mimeType );
+		cleanupItems++;
+				
+	    if ( aMessageData->AttachmentArray().Count() )
+            {
+            RFile handle = SendUiUtils::OpenFileHandleL(
+                aMessageData->AttachmentArray().MdcaPoint( 0 ), iFs );
+            CleanupClosePushL( handle );
+            SendUiUtils::ResolveMimeTypeL( handle, *mimeType );
+            CleanupStack::PopAndDestroy( &handle );
+            }
+        else
+            {
+            SendUiUtils::ResolveMimeTypeL( aMessageData->AttachmentHandleArray()[0], *mimeType );
+            }
+    	}
+    TBool addMailService = EFalse;
+    TUid integratedEmailClientMtmUid;
+		
+    if ( iEmailClientIntegration )
+    	{
+    	CRepository* repository = NULL;
+    	TInt mtmPluginID = 0;
+    	TRAPD( ret, repository = CRepository::NewL( KCRUidSelectableDefaultEmailSettings ) );
+    	
+    	if(ret == KErrNone)
+    	    {
+    	    //Get Email application mtm plugin ID
+    	    repository->Get( KIntegratedEmailAppMtmPluginId, mtmPluginID ); 
+    	    }
+
+    	delete repository;
+    	integratedEmailClientMtmUid = TUid::Uid(mtmPluginID);
+    	for( i = 0 ; i < iSendingServices.Count(); i++ )
+    		{
+    		TUid serviceUid = iSendingServices[i]->ServiceId();
+    		// Check if it is found in sendingServices and it's valid, then hide
+    		if ( integratedEmailClientMtmUid == iSendingServices[i]->ServiceId() && 
+    				CheckServiceCapabilities( serviceUid, aRequiredCapabilities ) &&
+    				CanSendContentL( serviceUid, 
+    							     iSendingServices[i]->ServiceProviderId(), 
+    							     aMessageData, mimeType ) )
+    			{
+    			addMailService = ETrue;
+    			}
+    		}
+    	
+    	}
+
+    // Filter available ECom services and add to list item array.
+    // Capability based filtering: CheckServiceCapabilities
+    // Content based filtering: CanSendContentL
+    // "dimmable array" filtering: done here
+    TInt serviceFeatures;
+    for( i = 0 ; i < iSendingServices.Count(); i++ )
+        {
+        dimService = EFalse;
+        TUid serviceUid = iSendingServices[i]->ServiceId();
+        TUid serviceProviderUid = iSendingServices[i]->ServiceProviderId();
+        
+        if ( iSendingServices[i]->ServiceMenuName() == KNullDesC )
+            {
+            dimService = ETrue;
+            }
+        
+        TUid serviceTechnologyType = iSendingServices[i]->TechnologyTypeId();
+        TUid dimServiceUid;
+        for ( cc = 0; cc < iServicesToDim->Count(); cc++ )
+            {
+			dimServiceUid = (*iServicesToDim)[cc];
+            if ( dimServiceUid == serviceUid 
+            || dimServiceUid == serviceProviderUid
+            || dimServiceUid == serviceTechnologyType 
+            )
+                {
+                dimService = ETrue;
+                break;
+                }
+            }
+        if ( iEmailClientIntegration )
+            {
+            //Hide Email application (not the platform email) from "send" menu
+            if( integratedEmailClientMtmUid == iSendingServices[i]->ServiceId() )
+                {
+                dimService = ETrue;
+                }  
+            }
+		serviceFeatures = iSendingServices[i]->ServiceFeatures();
+        if ( iEmailClientIntegration )
+        	{
+        	//If there is a mailbox created by integrated mail client then 
+        	//put SMTP MTM ("Email") in the "send" menu, by changing the 
+        	//serviceFeature    
+        	if ( addMailService && 
+        		 ( iSendingServices[i]->ServiceId() == KUidMsgTypeSMTP ) )
+        		{
+        		serviceFeatures = 0;
+        		addMailService = EFalse; //MailService must be added only once
+        		}
+        	}       
+        if ( !dimService &&
+             !( serviceFeatures & CSendingServiceInfo::EServiceInValid ) &&
+             !( serviceFeatures & CSendingServiceInfo::EServiceHidden )
+             &&  CheckServiceCapabilities( serviceUid, aRequiredCapabilities ) &&
+             CanSendContentL( serviceUid, serviceProviderUid, aMessageData, mimeType ) )
+            {
+            if ( aMenuType == CSendUi::ESendMenu )
+                {
+                aListItems.AppendL(iSendingServices[i]->ServiceMenuName() );
+                }
+            else if ( aMenuType == CSendUi::EWriteMenu )
+                {
+                aListItems.AppendL(iSendingServices[i]->ServiceName() );
+                }
+
+            aListItemUids.AppendL( serviceUid );
+            }
+        }
+    CleanupStack::PopAndDestroy( cleanupItems );
+    }
+
+// -----------------------------------------------------------------------------
+// SortListL
+// Sets ECom services to correct positions in "Send"-list query.
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::SortListL(
+    CDesCArrayFlat&     aListItems,
+    CArrayFix<TUid>&    aListItemUids )
+    {
+    TInt insertIndex(0);
+    TUid positionUid;   
+    TInt j;
+    // set the services into correct order. The order is predefined in the resources.
+    for ( TInt i = 0; i < iSendUiServicesOrderArray->Count() ; i++ )
+        {
+        positionUid = TUid::Uid( (*iSendUiServicesOrderArray)[i] );
+        for (j = insertIndex; j < aListItems.Count(); j++ )
+            {
+            TUid tmp = aListItemUids[j];
+            if ( positionUid == aListItemUids[j] ) 
+                {
+                if ( j >= insertIndex )
+                    {
+                    HBufC* serviceName = aListItems[j].AllocL();
+                    CleanupStack::PushL( serviceName );
+
+                    aListItemUids.Delete( j );
+                    aListItems.Delete( j );
+
+                    aListItemUids.InsertL( insertIndex, positionUid );
+                    aListItems.InsertL( insertIndex, *serviceName );
+                    CleanupStack::PopAndDestroy( serviceName );
+                    insertIndex++;      
+                    }
+                else
+                    {
+                    // service already on the right place. Next.
+                    insertIndex++;  
+                    }
+                    
+                }
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------
+// ResetIsSending
+// Resets sending state flag.
+// ---------------------------------------------------------
+//    
+void CSendUiImpl::ResetIsSending( TAny* aAny )
+    {
+    *( (TBool*)aAny ) = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CheckServiceCapabilities
+// Compares ECom service sending capabilities to required capabilities.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CSendUiImpl::CheckServiceCapabilities(
+    TUid                    aServiceUid,
+    TSendingCapabilities    aRequiredCapabilities )
+    {
+    TInt i = 0;
+    TSendingCapabilities serviceCapabilities;
+
+    // No capabilities defined, uses content-based filtering
+    // or no capabilities required from service
+    if ( aServiceUid == KDrmLinkSender 
+         || aRequiredCapabilities.iFlags == TSendingCapabilities::EAllServices )
+        { 
+        return ETrue;
+        }
+
+    i = ResolveServiceIndex( aServiceUid );
+
+    if ( i != KErrNotFound )
+        {
+        return QueryCapabilities( i, aRequiredCapabilities );  
+        }
+    else
+        {
+        return EFalse;          
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSendUiImpl
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CSendUiImpl::CSendUiImpl()
+    :  iCoeEnv( CCoeEnv::Static() ),
+        iFs( iCoeEnv->FsSession() ),
+        iResourceLoader( *iCoeEnv )
+        
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CSendUiImpl::FeatureStatus
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::FeatureStatus( TInt aFeature, TInt &aNewFeatures, TInt aFeatureFlag )
+    {
+    if ( FeatureManager::FeatureSupported( aFeature ) )
+        {
+        // If Postcard only is supported,     aFeatureFlag is 0x00000001 ==> aNewFeatures == 0x00000001
+        // If Audio message is also supported aFeatureFlag is 0x00000002 ==> aNewFeatures == 0x00000003
+        // If MMSUpload is also supported,    aFeatureFlag is 0x00000004 ==> aNewFeatures == 0x00000007
+        aNewFeatures |= aFeatureFlag;
+        }
+    }
+// ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CSendUiImpl::ConstructL()
+    {
+    iSingleton = CSendUiSingleton::NewL();
+    //User::LeaveIfError( iFs.Connect() );
+    iFs.ShareProtected();
+
+    TParse* fp = new(ELeave) TParse(); 
+    fp->Set( KSendUiResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL );
+    iResourceFileName = fp->FullName();
+    delete fp;
+    fp = NULL;
+    
+    iResourceLoader.OpenL( iResourceFileName );
+
+    // Check for server launch
+    RProcess process;
+    TUid hostId = process.SecureId();
+    if ( hostId == KSendUiLauncherAppUid ) 
+        {
+        iServerAppLaunch = ETrue;
+        }
+   else
+        {
+        iServerAppLaunch = EFalse;
+        iSendUiServicesOrderArray = 
+            new ( ELeave ) CArrayFixFlat<TInt32>( KSendUiServiceOrderArrayGranularity );
+
+        TResourceReader reader;
+        iCoeEnv->CreateResourceReaderLC( reader, R_SENDUISERVICEORDER_ARRAY );
+        const TInt count = reader.ReadInt16();
+        for ( TInt loop = 0; loop < count; loop++ )
+            {
+            iSendUiServicesOrderArray->AppendL( reader.ReadInt32() );
+            }
+        CleanupStack::PopAndDestroy( ); // reader 
+        }
+
+    iPropertyObserver = CPropertyObserver::NewL( this );
+    TRAPD( err, GetServicesL() );
+    
+    if ( err )
+        {
+#ifdef _DEBUG
+        TBuf<256> buf;
+        buf.Format(_L("SendUi err"));
+        User::InfoPrint(buf);
+        LOGTEXT2(_L("Error %d while loading CenRep"), err );
+#endif
+        return;
+        }
+    iServicesToDim = new (ELeave) CArrayFixFlat<TUid>( KArrayGranularity );
+    FeatureManager::InitializeLibL();
+    
+    if ( FeatureManager::FeatureSupported( KFeatureIdEmailMceIntegration ) )
+    	{
+
+    	iEmailClientIntegration = ETrue;
+    	}
+    else
+    	{
+
+    	iEmailClientIntegration = EFalse;
+    	}   
+    FeatureManager::UnInitializeLib();
+    }
+
+// end of file
+