--- /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
+