--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmsengine/clientmtm/src/mmsnotificationclient.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,1056 @@
+/*
+* 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:
+* A Client MTM to access MMS notifications in a manual fetch mode.
+* All this is needed to support new mtm type for Symbian OS messaging
+* UI components.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <msvids.h>
+#include "mmsheaders.h"
+#include "mmsnotificationclient.h"
+#include "mmscmds.h"
+#include "mmsmessageoperation.h"
+#include "mmsmmboxviewheaders.h"
+#include "mmssettings.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KMmsAttributeArrayGranularity = 8;
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// ==================== LOCAL FUNCTIONS ====================
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::NewL
+// ---------------------------------------------------------
+//
+EXPORT_C CMmsNotificationClientMtm* CMmsNotificationClientMtm::NewL(
+ CRegisteredMtmDll& aRegisteredMtmDll,
+ CMsvSession& aSession )
+ {
+ CMmsNotificationClientMtm* self = new ( ELeave ) CMmsNotificationClientMtm(
+ aRegisteredMtmDll, aSession );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::CMmsNotificationClientMtm
+// ---------------------------------------------------------
+//
+CMmsNotificationClientMtm::CMmsNotificationClientMtm(
+ CRegisteredMtmDll& aRegisteredMtmDll,
+ CMsvSession& aSession )
+ : CMmsClientMtm( aRegisteredMtmDll, aSession )
+ {
+ __ASSERT_DEBUG( Type() == KUidMsgMMSNotification, gPanic( EMmsBadMtmTypeUid ) );
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::~CMmsNotificationClientMtm
+// ---------------------------------------------------------
+//
+CMmsNotificationClientMtm::~CMmsNotificationClientMtm()
+ {
+
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::ConstructL
+//
+// ---------------------------------------------------------
+//
+void CMmsNotificationClientMtm::ConstructL()
+ {
+ // First loading settings
+ iMmsSettings = CMmsSettings::NewL();
+ iMmsSettings->LoadSettingsL();
+ // Get the base values to detect changes
+ iHomeMode = iMmsSettings->ReceivingModeHome();
+ iRoamingMode = iMmsSettings->ReceivingModeForeign();
+ iAccessPointCount = iMmsSettings->AccessPointCount();
+
+ iMessageDrive = EDriveC;
+ TInt error = KErrNone;
+
+ TRAP ( error, { iMessageDrive = Session().CurrentDriveL(); } );
+
+ if ( error != KErrNone )
+ {
+ // if cannot ask, use default
+ iMessageDrive = EDriveC;
+ }
+
+ // Notification client mtm does not create new service
+ iServiceId = iMmsSettings->Service();
+
+ iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+
+ iAttributes = new( ELeave ) CDesCArrayFlat( KMmsAttributeArrayGranularity );
+
+ // Set the original context to the service entry
+ SwitchCurrentEntryL( iServiceId );
+ }
+
+// ---------------------------------------------------------
+// CMmsClientMtm::QueryCapability
+// ---------------------------------------------------------
+//
+TInt CMmsNotificationClientMtm::QueryCapability(
+ TUid /*aCapability*/,
+ TInt& /*aResponse*/ )
+ {
+ // Nothing Supported at the moment
+ return KErrNotSupported;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::ForwardL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::ForwardL(
+ TMsvId aDestination,
+ TMsvPartList /*aPartList*/,
+ TRequestStatus& aCompletionStatus )
+ {
+ //
+ // Actual creation is done synchronously below
+ //
+ TMsvId id = CreateForwardEntryL( aDestination );
+
+ //
+ // This method has to be asynchronous..
+ //
+ TPckgC < TMsvId > progress = id;
+ return CMsvCompletedOperation::NewL( Session(), Type(), progress,
+ KMsvLocalServiceIndexEntryId, aCompletionStatus );
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::CreateForwardEntryL
+// ---------------------------------------------------------
+//
+TMsvId CMmsNotificationClientMtm::CreateForwardEntryL( TMsvId aDestination )
+ {
+ //
+ // Check that current context is valid
+ //
+ if( iMsvEntry->Entry().iType != KUidMsvMessageEntry
+ || iMsvEntry->Entry().iMtm != KUidMsgMMSNotification )
+ {
+ User::Leave( KErrUnknown );
+ }
+
+ // It is assumed that a created forward entry can not be saved to drafts.
+ // I.e. the application calling this, is responsible to take care that
+ // the entry is either SENT or DESTROYED.
+
+ //
+ // Load entry to local cache if necessary
+ //
+ if( iMmsHeaders->ContentLocation() == TPtrC8() )
+ {
+ LoadMessageL();
+ }
+
+ //
+ // Create new Mms message object into aDestination folder
+ //
+ TMsvId forwardId = CMmsMessageOperation::CreateForwardWithoutRetrievalL(
+ Session(),
+ *iMmsHeaders,
+ iMsvEntry->EntryId(),
+ aDestination,
+ iServiceId );
+
+ return forwardId;
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::SendL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::SendL(
+ TRequestStatus& aCompletionStatus,
+ const TTime aSendingTime )
+ {
+ //
+ // Is it possible to proceed with the operation...
+ // If yes, the notification is marked as "further-operations-not-allowed"
+ //
+ TMsvId relatedNotificationId = iMmsHeaders->RelatedEntry();
+ TInt retval = ReserveNotificationOperationL( relatedNotificationId, KMmsOperationForward );
+ if( retval != KErrNone )
+ {
+ TPckgC < TMsvId > progress = relatedNotificationId;
+ return CMsvCompletedOperation::NewL(
+ Session(),
+ KUidMsgMMSNotification,
+ progress, // progress contains the related entry id
+ iServiceId,
+ aCompletionStatus,
+ KErrInUse);
+ }
+
+ //
+ // Create the selection to be sent
+ //
+ CMsvEntrySelection* selection = new( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( selection ); // ***
+ selection->AppendL( iMsvEntry->Entry().Id() );
+
+ //
+ // Make sure the message is in OUTBOX
+ //
+ TMsvId currentParent = iMsvEntry->Entry().Parent();
+ if ( currentParent != KMsvGlobalOutBoxIndexEntryId )
+ {
+ CMsvEntry* cEntry = NULL;
+ cEntry = Session().GetEntryL( currentParent );
+ CleanupStack::PushL( cEntry );
+ cEntry->MoveL( iMsvEntry->Entry().Id(), KMsvGlobalOutBoxIndexEntryId );
+ CleanupStack::PopAndDestroy( cEntry );
+ }
+
+ //
+ // Create parameters structure
+ //
+ TCommandParameters parameters;
+ TTime now;
+ now.UniversalTime();
+ if ( aSendingTime > now )
+ {
+ aSendingTime.SecondsFrom( now, parameters.iInitialDelay );
+ }
+ TCommandParametersBuf paramPack( parameters );
+
+ //
+ // Call Server MTM
+ //
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsScheduledForward,
+ *selection,
+ paramPack,
+ aCompletionStatus );
+
+ //
+ // Cleanup and return
+ //
+ CleanupStack::PopAndDestroy( selection );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::SendL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::SendL(
+ CMsvEntrySelection& /*aSelection*/,
+ TRequestStatus& /*aCompletionStatus*/,
+ TTime /*aSendingTime*/ )
+ {
+ User::Leave( KErrNotSupported );
+ return NULL; // makes the compiler happy
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::ReserveNotificationOperationL
+// ---------------------------------------------------------
+//
+TInt CMmsNotificationClientMtm::ReserveNotificationOperationL(
+ TMsvId aNotifId,
+ const TUint32 aOperation )
+ {
+ //
+ // Get hands on index entry based on entryId
+ //
+ CMsvEntry* cEntry = NULL;
+ cEntry = Session().GetEntryL( aNotifId );
+ CleanupStack::PushL( cEntry ); // ***
+ TMsvEntry tEntry = cEntry->Entry();
+
+ //
+ // Check that entry is a notification
+ //
+ if( cEntry->Entry().iType != KUidMsvMessageEntry
+ || cEntry->Entry().iMtm != KUidMsgMMSNotification )
+ {
+ CleanupStack::PopAndDestroy( cEntry );
+ return KErrNotSupported;
+ }
+
+ //
+ // Make some checks concerning the current status of notification and
+ // return with error if reservation is not possible
+ //
+ // if operation is forbidden OR
+ // if ( (the aOperation is fetch or forward) and notification is deleted successfully from mmbox)
+ if( tEntry.iMtmData2 & KMmsNewOperationForbidden ||
+ ( ( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward ) &&
+ tEntry.iMtmData2 & KMmsOperationFinished &&
+ ! ( tEntry.iMtmData2 & KMmsOperationResult ) &&
+ ! ( tEntry.iMtmData2 & KMmsStoredInMMBox ) &&
+ tEntry.iMtmData2 & KMmsOperationDelete ) )
+ {
+ CleanupStack::PopAndDestroy( cEntry );
+ return KErrInUse;
+ }
+
+ //
+ // Set the flags
+ //
+ // reserve the operation
+ MarkNotificationOperationReserved( tEntry, aOperation );
+ tEntry.SetReadOnly( EFalse );
+
+ //
+ // Save the entry
+ //
+ cEntry->ChangeL( tEntry );
+ CleanupStack::PopAndDestroy( cEntry );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::MarkFreeNotificationsReservedL
+// ---------------------------------------------------------
+//
+void CMmsNotificationClientMtm::MarkFreeNotificationsReservedL(
+ CMsvEntrySelection& aNotifications, const TUint32 aOperation )
+ {
+ TInt count = aNotifications.Count();
+ if ( count == 0 )
+ {
+ return;
+ }
+ CMsvEntry* clientEntry = Session().GetEntryL( aNotifications.At( 0 ));
+ CleanupStack::PushL( clientEntry );
+
+ for ( TInt i = aNotifications.Count() - 1 ; i >= 0 ; i-- )
+ {
+ TBool drop = EFalse;
+ TBool alreadyMarked = EFalse;
+
+ clientEntry->SetEntryL( aNotifications.At( i ) );
+ TMsvEntry entry = clientEntry->Entry();
+ TMsvId duplicate = KMsvNullIndexEntryId;
+ if ( FreeNotification( entry, aOperation ) )
+ {
+ // Check possible duplicate, if mmbox folder even exists
+ TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
+ if ( mmboxFolder != KMsvNullIndexEntryId )
+ {
+ TMsvId parent = entry.Parent();
+
+ CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+ CleanupStack::PushL( mmsHeaders );
+ CMsvStore* store = clientEntry->ReadStoreL();
+ CleanupStack::PushL( store );
+ mmsHeaders->RestoreL( *store );
+ CleanupStack::PopAndDestroy( store );
+ store = NULL;
+
+ if ( parent == KMsvGlobalInBoxIndexEntryId )
+ {
+
+ FindDuplicateNotificationL( mmboxFolder,
+ *mmsHeaders, duplicate );
+ }
+ else if ( parent == mmboxFolder )
+ {
+ FindDuplicateNotificationL( KMsvGlobalInBoxIndexEntryId,
+ *mmsHeaders, duplicate );
+ }
+ else
+ {
+ // keep LINT happy
+ }
+ if ( duplicate != KMsvNullIndexEntryId )
+ {
+ // check if duplicate is free for a operation
+ clientEntry->SetEntryL( duplicate );
+ TMsvEntry dupEntry = clientEntry->Entry();
+ if ( FreeNotification( dupEntry, aOperation ))
+ {
+ // if original notification is in mmbox folder
+ // mark the duplicate reserved too.
+ if ( parent == mmboxFolder )
+ {
+ MarkNotificationOperationReserved( dupEntry, aOperation );
+ clientEntry->ChangeL( dupEntry );
+
+ clientEntry->SetEntryL( aNotifications.At( i ) );
+ entry = clientEntry->Entry();
+ MarkNotificationOperationReserved( entry, aOperation );
+ entry.SetReadOnly( EFalse );
+ clientEntry->ChangeL( entry );
+ alreadyMarked = ETrue;
+
+ store = clientEntry->EditStoreL();
+ CleanupStack::PushL( store );
+ mmsHeaders->RestoreL( *store );
+ mmsHeaders->SetRelatedEntry( duplicate );
+ mmsHeaders->StoreL( *store );
+ store->CommitL();
+ CleanupStack::PopAndDestroy( store );
+ store = NULL;
+ }
+ clientEntry->SetEntryL( aNotifications.At( i ) );
+
+ }
+ else // duplicate is not free-> original notification has to be dropped
+ {
+ drop = ETrue;
+ }
+
+ }
+ CleanupStack::PopAndDestroy( mmsHeaders );
+ }
+
+ }
+ else // original notification is not free
+ {
+ drop = ETrue;
+ }
+
+ if ( drop )
+ {
+ // Remove the entry from selection
+ aNotifications.Delete( i );
+ }
+ else // mark original notification reserved, unless it is already marked
+ {
+ if ( !alreadyMarked)
+ {
+ clientEntry->SetEntryL( aNotifications.At( i ) );
+ entry = clientEntry->Entry();
+ MarkNotificationOperationReserved( entry, aOperation );
+ entry.SetReadOnly( EFalse );
+ clientEntry->ChangeL( entry );
+ }
+ }
+ }
+ aNotifications.Compress();
+
+ CleanupStack::PopAndDestroy( clientEntry );
+
+ }
+
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::FreeNotification
+// ---------------------------------------------------------
+//
+TBool CMmsNotificationClientMtm::FreeNotification( TMsvEntry& aEntry, const TUint32 aOperation )
+ {
+ if ( aEntry.iMtm != KUidMsgMMSNotification)
+ {
+ return EFalse;
+ }
+ if ( aEntry.iMtmData2 & KMmsNewOperationForbidden ||
+ ( aEntry.iMtmData2 & KMmsOperationFinished &&
+ !( aEntry.iMtmData2 & KMmsOperationResult ) &&
+ !( aEntry.iMtmData2 & KMmsStoredInMMBox ) &&
+ ( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward )))
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+
+ }
+
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::MarkNotificationOperationReserved
+// ---------------------------------------------------------
+//
+void CMmsNotificationClientMtm::MarkNotificationOperationReserved( TMsvEntry& aEntry,
+ const TUint32 aOperation )
+ {
+ aEntry.iMtmData2 &= ~KMmsOperationIdentifier; // clear possible old operation
+ aEntry.iMtmData2 |= KMmsNewOperationForbidden; // forbidden
+ aEntry.iMtmData2 |= KMmsOperationOngoing; // operation is active
+ aEntry.iMtmData2 |= aOperation; // operation
+ aEntry.iMtmData2 &= ~KMmsOperationFinished; // not finished
+ aEntry.iMtmData2 &= ~KMmsOperationResult; // not failed
+ }
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::FindDuplicateNotificationL
+// ---------------------------------------------------------
+//
+void CMmsNotificationClientMtm::FindDuplicateNotificationL( TMsvId aParent,
+ CMmsHeaders& aHeaders,
+ TMsvId& aDuplicate )
+ {
+
+ aDuplicate = KMsvNullIndexEntryId;
+ if ( aParent == KMsvNullIndexEntryId )
+ {
+ return;
+ }
+
+ CMsvEntry* cEntry = Session().GetEntryL( aParent );
+ CleanupStack::PushL( cEntry );
+
+ CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgMMSNotification );
+ CleanupStack::PushL( selection );
+
+ TInt count = selection->Count();
+ if ( count == 0 )
+ {
+ CleanupStack::PopAndDestroy( selection );
+ CleanupStack::PopAndDestroy( cEntry );
+ return;
+ }
+
+ CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+ CleanupStack::PushL( mmsHeaders );
+
+ for ( TInt i = count; i > 0 && ( aDuplicate == KMsvNullIndexEntryId ); i-- )
+ {
+ cEntry->SetEntryL( selection->At( i - 1 ) );
+
+ CMsvStore* store = cEntry->ReadStoreL();
+ CleanupStack::PushL( store );
+ mmsHeaders->RestoreL( *store );
+ CleanupStack::PopAndDestroy( store );
+
+ // content location must match
+ if ( mmsHeaders->ContentLocation().Compare( aHeaders.ContentLocation() ) == 0 )
+ {
+ aDuplicate = selection->At( i - 1 );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( mmsHeaders );
+ CleanupStack::PopAndDestroy( selection );
+ CleanupStack::PopAndDestroy( cEntry );
+ }
+
+// ---------------------------------------------------------
+// CMmsClientNotificationMtm::GetExtendedText
+// ---------------------------------------------------------
+//
+const TPtrC CMmsNotificationClientMtm::GetExtendedText() const
+ {
+ return iMmsHeaders->ExtendedNotification();
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::FetchMessagesL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::FetchMessagesL(
+ const CMsvEntrySelection& aSelection,
+ TRequestStatus& aCompletionStatus )
+ {
+ if ( aSelection.Count() == 0 )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ CMsvEntrySelection* notifications = aSelection.CopyLC();
+
+ // mark free notifications reserved. Others are dropped out.
+ MarkFreeNotificationsReservedL( *notifications, KMmsOperationFetch );
+
+ // check if none of the entries are allowed to start fetch
+ if ( notifications->Count() == 0 )
+ {
+ // leave will destroy reserved items from cleanupstack
+ User::Leave( KErrNotSupported );
+ }
+
+ TCommandParameters parameters; // initialized to zero
+ TCommandParametersBuf paramPack( parameters );
+
+ // Fetch messages
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsScheduledReceiveForced,
+ *notifications,
+ paramPack,
+ aCompletionStatus );
+
+ CleanupStack::PopAndDestroy( notifications );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::FetchMessageL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::FetchMessageL(
+ TMsvId aUid,
+ TRequestStatus& aCompletionStatus )
+ {
+ CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( selection );
+ selection->AppendL( aUid );
+
+ // Mark the notification reserved for fetching is possible
+ MarkFreeNotificationsReservedL( *selection, KMmsOperationFetch );
+
+ // if notification is not allowed to be fetched,
+ // the notification is dropped from selection.
+ if ( selection->Count() == 0 )
+ {
+ CleanupStack::PopAndDestroy( selection );
+ return NULL;
+ }
+
+ TCommandParameters parameters; // initialized to zero
+ TCommandParametersBuf paramPack( parameters );
+
+ // Fetch the message
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsScheduledReceiveForced,
+ *selection,
+ paramPack,
+ aCompletionStatus );
+
+ CleanupStack::PopAndDestroy( selection );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::FetchAllL
+// ---------------------------------------------------------
+//
+
+CMsvOperation* CMmsNotificationClientMtm::FetchAllL( TRequestStatus& aCompletionStatus,
+ TBool aForced )
+ {
+ // List notifications that have no active operation
+ CMsvEntrySelection* notifications = ListNotificationsL();
+ if ( notifications->Count() == 0 )
+ {
+ delete notifications;
+ notifications = NULL;
+ User::Leave( KErrNotFound );
+ }
+ CleanupStack::PushL( notifications );
+
+ // Loop through the notifications and reserve them for the operation
+ TInt retval = KErrNone;
+ TInt count = notifications->Count();
+ for ( TInt i = count; i > 0; i-- )
+ {
+ retval = ReserveNotificationOperationL( notifications->At( i - 1 ), KMmsOperationFetch );
+ if( retval != KErrNone )
+ {
+ // Remove the entry from selection
+ notifications->Delete( i - 1 );
+ }
+ }
+
+ TCommandParameters parameters; // initialized to zero
+ TCommandParametersBuf paramPack( parameters );
+
+ // Fetch the message
+ CMsvOperation* op = NULL;
+ if ( aForced )
+ {
+ op = InvokeAsyncFunctionL(
+ EMmsScheduledReceiveForced,
+ *notifications,
+ paramPack,
+ aCompletionStatus );
+ }
+ else
+ {
+ op = InvokeAsyncFunctionL(
+ EMmsScheduledReceive,
+ *notifications,
+ paramPack,
+ aCompletionStatus );
+ }
+
+ CleanupStack::PopAndDestroy( notifications );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::NotificationCount
+// ---------------------------------------------------------
+//
+TInt CMmsNotificationClientMtm::NotificationCount()
+ {
+ TInt numberOfNotifications = -1;
+
+ TInt error = KErrNone;
+ CMsvEntrySelection* notifications = NULL;
+
+ TRAP( error,
+ { notifications = ListNotificationsL();
+ });
+
+ if ( error == KErrNone )
+ {
+ numberOfNotifications = notifications->Count();
+ }
+
+ delete notifications;
+ notifications = NULL;
+
+ return numberOfNotifications;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::ListNotificationsL
+// ---------------------------------------------------------
+//
+CMsvEntrySelection* CMmsNotificationClientMtm::ListNotificationsL()
+ {
+ return CMmsClientMtm::ListNotificationsInInboxL();
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::DeleteNotificationL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::DeleteNotificationL(
+ const CMsvEntrySelection& aSelection,
+ TMmsDeleteOperationType aDeleteType,
+ TRequestStatus& aCompletionStatus )
+ {
+
+ if ( aSelection.Count() == 0 )
+ {
+ // if nothing to delete, operation is complete
+ TPckgC < TMsvId > progress = 0;
+ return CMsvCompletedOperation::NewL( Session(), Type(), progress,
+ KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
+ }
+
+ //
+ // aDeleteType has to be delivered to server side.
+ // Using TCommandParameters.iError for it on purpose.
+ //
+ TCommandParameters parameters;
+ parameters.iError = aDeleteType;
+ TCommandParametersBuf paramPack( parameters );
+
+ //
+ // Modifying indexentries
+ //
+ CMsvEntry* cEntry = NULL;
+ cEntry = Session().GetEntryL( aSelection.At( 0 ) );
+ CleanupStack::PushL( cEntry ); // ***
+ for ( TInt i = 0; i < aSelection.Count(); i++ )
+ {
+ cEntry->SetEntryL( aSelection.At( i ) );
+ TMsvEntry tEntry = cEntry->Entry();
+ tEntry.SetReadOnly( EFalse );
+ cEntry->ChangeL( tEntry );
+ }
+ CleanupStack::PopAndDestroy( cEntry );
+
+ //
+ // NOTE: Notification delete operations perform majority of the work in
+ // the server side. This includes also notification reservation for the operation.
+ //
+
+ //
+ // Calling server side
+ //
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsScheduledNotificationDelete,
+ aSelection,
+ paramPack,
+ aCompletionStatus );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::UnscheduledDeleteNotificationL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::UnscheduledDeleteNotificationL(
+ const CMsvEntrySelection& aSelection,
+ TMmsDeleteOperationType aDeleteType,
+ TRequestStatus& aCompletionStatus )
+ {
+
+ if ( aSelection.Count() == 0 )
+ {
+ // if nothing to delete, operation is complete
+ TPckgC < TMsvId > progress = 0;
+ return CMsvCompletedOperation::NewL( Session(), Type(), progress,
+ KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
+ }
+
+ //
+ // aDeleteType has to be delivered to server side.
+ // Using TCommandParameters.iError for it on purpose.
+ //
+ TCommandParameters parameters;
+ parameters.iError = aDeleteType;
+ TCommandParametersBuf paramPack( parameters );
+
+ //
+ // NOTE: Notification delete operations perform majority of the work in
+ // the server side. This includes also notification reservation for the operation.
+ //
+
+ //
+ // Calling server side
+ //
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsNotificationDelete,
+ aSelection,
+ paramPack,
+ aCompletionStatus );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::DeleteAllNotificationsL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::DeleteAllNotificationsL(
+ TMmsDeleteOperationType aDeleteType,
+ TRequestStatus& aCompletionStatus )
+ {
+ //
+ // Get selection of all the notifications in Inbox
+ // (operations that do not have ongoing operations)
+ //
+ CMsvEntrySelection* selection = ListNotificationsL();
+
+ if ( selection->Count() == 0 )
+ {
+ delete selection;
+ selection = NULL;
+ // if nothing to delete, operation is complete
+ TPckgC < TMsvId > progress = 0;
+ return CMsvCompletedOperation::NewL( Session(), Type(), progress,
+ KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
+ }
+
+ CleanupStack::PushL( selection );
+
+ //
+ // Call DeleteNotificationL with the selection just created
+ //
+ CMsvOperation* op = DeleteNotificationL(
+ *selection,
+ aDeleteType,
+ aCompletionStatus );
+ CleanupStack::PopAndDestroy( selection );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::DeleteForwardEntryL
+// ---------------------------------------------------------
+//
+void CMmsNotificationClientMtm::DeleteForwardEntryL( const CMsvEntrySelection& aSelection )
+ {
+ //
+ // Loop through the selection of forward entries
+ //
+ TInt count = aSelection.Count();
+ for( TInt index = 0; index < count; index++ )
+ {
+ iMsvEntry->SetEntryL( aSelection.At( index ) );
+ TMsvEntry tEntry = iMsvEntry->Entry();
+ // Test entry type
+ if( tEntry.iType != KUidMsvMessageEntry ||
+ tEntry.iMtm != KUidMsgMMSNotification ||
+ !( tEntry.iMtmData1 & KMmsMessageForwardReq ) )
+ {
+ continue;
+ }
+ // Test entry location
+ TMsvId parentId = tEntry.Parent();
+ if( ( parentId != KMsvGlobalOutBoxIndexEntryId ) &&
+ ( parentId != KMsvSentEntryId ) )
+ {
+ continue;
+ }
+ // Test that entry is not in a middle of some other action
+ if( tEntry.SendingState() == KMsvSendStateSending )
+ {
+ // Too late to delete
+ continue;
+ }
+ else
+ {
+ // Quickly "reserve" the entry for deletion
+ tEntry.SetSendingState( KMsvSendStateSuspended );
+ iMsvEntry->ChangeL( tEntry );
+ }
+ //
+ // Entry will do; it will be deleted.
+ //
+
+ // But first clearing possible related notification
+ CMsvStore* store = iMsvEntry->ReadStoreL();
+ CleanupStack::PushL( store ); // ***
+ CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+ CleanupStack::PushL( mmsHeaders );
+ mmsHeaders->RestoreL( *store );
+ TMsvId relatedId = mmsHeaders->RelatedEntry();
+ CleanupStack::PopAndDestroy( mmsHeaders );
+ CleanupStack::PopAndDestroy( store );
+
+ // If forward entry has a "related id" (i.e. id of the notification),
+ // context is changed to it and it will be cleared.
+ if( relatedId != KMsvNullIndexEntryId )
+ {
+ // Change to related notification
+ iMsvEntry->SetEntryL( relatedId );
+ tEntry = iMsvEntry->Entry();
+ // "Clear" the flags
+ tEntry.iMtmData2 &= ~KMmsOperationIdentifier; // clear possible old operations
+ tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // not forbidden
+ tEntry.iMtmData2 &= ~KMmsOperationOngoing; // not ongoing
+ tEntry.iMtmData2 &= ~KMmsOperationFinished; // not finished (this is notification's initial state)
+ tEntry.iMtmData2 &= ~KMmsOperationResult; // clear also the result flag ("assuming OK")
+ tEntry.SetReadOnly( ETrue );
+ iMsvEntry->ChangeL( tEntry );
+ }
+
+ // Activating parent entry of the forward entry
+ iMsvEntry->SetEntryL( parentId );
+ // Delete forward entry
+ iMsvEntry->DeleteL( aSelection.At( index ) );
+ } // for loop
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::MmboxInfoL
+// ---------------------------------------------------------
+//
+TBool CMmsNotificationClientMtm::MmboxInfoL( TMmboxInfo& aMmboxInfo )
+ {
+ // check first, if quota information is available.
+ TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
+ CMsvEntry* cEntry = Session().GetEntryL( KMsvLocalServiceIndexEntryId );
+ CleanupStack::PushL( cEntry );
+ TInt pushedToStack = 1;
+
+ cEntry->SetEntryL( mmboxFolder );
+ // Show invisible entries
+ cEntry->SetSortTypeL( TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByIdReverse, ETrue ) );
+ CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgTypeMultimedia );
+ CleanupStack::PushL( selection );
+ pushedToStack++;
+
+ TBool quotaInfoAvailable = EFalse;
+
+ if ( selection->Count() > 0 )
+ {
+ cEntry->SetEntryL( selection->At( 0 ));
+ CMsvStore* store = cEntry->ReadStoreL();
+ CleanupStack::PushL( store );
+ pushedToStack++;
+ CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
+ CleanupStack::PushL( mmsHeaders );
+ pushedToStack++;
+ mmsHeaders->RestoreL( *store );
+
+ // Get quota info
+ CMmsMMBoxViewHeaders& viewHeaders = mmsHeaders->MMBoxViewHeadersL();
+
+ aMmboxInfo.mmboxTotalInBytes = viewHeaders.MMBoxTotalSize();
+ aMmboxInfo.mmboxTotalInMessageCount = viewHeaders.MMBoxTotalNumber();
+ aMmboxInfo.mmboxQuotaInBytes = viewHeaders.MMBoxQuotaSize();
+ aMmboxInfo.mmboxQuotaInMessageCount = viewHeaders.MMBoxQuotaNumber();
+
+ // get Date info
+ TMsvEntry tEntry = cEntry->Entry();
+ aMmboxInfo.date = tEntry.iDate;
+
+ // error
+ aMmboxInfo.error = tEntry.iError;
+
+ quotaInfoAvailable = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( pushedToStack );
+ return quotaInfoAvailable;
+ }
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::UpdateMmBoxListL
+// ---------------------------------------------------------
+//
+CMsvOperation* CMmsNotificationClientMtm::UpdateMmBoxListL(
+ TRequestStatus& aCompletionStatus )
+ {
+ TCommandParameters parameters; // initialized to zero
+ TCommandParametersBuf paramPack( parameters );
+
+ CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
+ CleanupStack::PushL( selection );
+ selection->AppendL( iServiceId );
+
+ // Update mmbox list
+ CMsvOperation* op = InvokeAsyncFunctionL(
+ EMmsUpdateMmboxList,
+ *selection,
+ paramPack,
+ aCompletionStatus );
+
+ CleanupStack::PopAndDestroy( selection );
+ return op;
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm::GetMmboxFolderL
+// ---------------------------------------------------------
+//
+TMsvId CMmsNotificationClientMtm::GetMmboxFolderL()
+ {
+ return iMmsSettings->MMBoxFolder();
+ }
+
+// ---------------------------------------------------------
+// CMmsNotificationClientMtm
+// ---------------------------------------------------------
+//
+const TPtrC CMmsNotificationClientMtm::GetApplicationId() const
+ {
+ return iMmsHeaders->ApplicId();
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+// End of File
+
+