mmsengine/clientmtm/src/mmsnotificationclient.cpp
changeset 0 72b543305e3a
child 23 238255e8b033
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *     A Client MTM to access MMS notifications in a manual fetch mode.
       
    16 *     All this is needed to support new mtm type for Symbian OS messaging
       
    17 *     UI components.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDE FILES
       
    24 #include <msvids.h>
       
    25 #include "mmsheaders.h"
       
    26 #include "mmsnotificationclient.h"
       
    27 #include "mmscmds.h"
       
    28 #include "mmsmessageoperation.h"
       
    29 #include "mmsmmboxviewheaders.h"
       
    30 #include "mmssettings.h"
       
    31 
       
    32 // EXTERNAL DATA STRUCTURES
       
    33 
       
    34 // EXTERNAL FUNCTION PROTOTYPES  
       
    35 
       
    36 // CONSTANTS
       
    37 
       
    38 // MACROS
       
    39 
       
    40 // LOCAL CONSTANTS AND MACROS
       
    41 const TInt KMmsAttributeArrayGranularity = 8;
       
    42 
       
    43 // MODULE DATA STRUCTURES
       
    44 
       
    45 // LOCAL FUNCTION PROTOTYPES
       
    46 
       
    47 // ==================== LOCAL FUNCTIONS ====================
       
    48 
       
    49 
       
    50 // ================= MEMBER FUNCTIONS =======================
       
    51 
       
    52 // ---------------------------------------------------------
       
    53 // CMmsClientNotificationMtm::NewL
       
    54 // ---------------------------------------------------------
       
    55 //
       
    56 EXPORT_C CMmsNotificationClientMtm* CMmsNotificationClientMtm::NewL(
       
    57     CRegisteredMtmDll& aRegisteredMtmDll,
       
    58     CMsvSession& aSession )
       
    59     {
       
    60     CMmsNotificationClientMtm* self = new ( ELeave ) CMmsNotificationClientMtm(
       
    61         aRegisteredMtmDll, aSession );
       
    62 
       
    63     CleanupStack::PushL( self );
       
    64     self->ConstructL();
       
    65     CleanupStack::Pop( self );
       
    66 
       
    67     return self;
       
    68     }
       
    69 
       
    70 
       
    71 // ---------------------------------------------------------
       
    72 // CMmsClientNotificationMtm::CMmsNotificationClientMtm
       
    73 // ---------------------------------------------------------
       
    74 //
       
    75 CMmsNotificationClientMtm::CMmsNotificationClientMtm(
       
    76     CRegisteredMtmDll& aRegisteredMtmDll,
       
    77     CMsvSession& aSession )
       
    78     : CMmsClientMtm( aRegisteredMtmDll, aSession )
       
    79     {
       
    80     __ASSERT_DEBUG( Type() == KUidMsgMMSNotification, gPanic( EMmsBadMtmTypeUid ) );
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------
       
    84 // CMmsClientNotificationMtm::~CMmsNotificationClientMtm
       
    85 // ---------------------------------------------------------
       
    86 //
       
    87 CMmsNotificationClientMtm::~CMmsNotificationClientMtm()
       
    88     {
       
    89     
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------
       
    93 // CMmsClientNotificationMtm::ConstructL
       
    94 // 
       
    95 // ---------------------------------------------------------
       
    96 //
       
    97 void CMmsNotificationClientMtm::ConstructL()
       
    98     {
       
    99     // First loading settings
       
   100     iMmsSettings = CMmsSettings::NewL();
       
   101     iMmsSettings->LoadSettingsL();
       
   102     // Get the base values to detect changes
       
   103     iHomeMode = iMmsSettings->ReceivingModeHome();
       
   104     iRoamingMode = iMmsSettings->ReceivingModeForeign();
       
   105     iAccessPointCount = iMmsSettings->AccessPointCount();
       
   106     
       
   107     iMessageDrive = EDriveC;
       
   108     TInt error = KErrNone;
       
   109 
       
   110     TRAP ( error, { iMessageDrive = Session().CurrentDriveL(); } );
       
   111 
       
   112     if ( error != KErrNone )
       
   113         {
       
   114         // if cannot ask, use default
       
   115         iMessageDrive = EDriveC;
       
   116         }
       
   117 
       
   118     // Notification client mtm does not create new service
       
   119     iServiceId = iMmsSettings->Service();
       
   120 
       
   121     iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
   122 
       
   123     iAttributes  = new( ELeave ) CDesCArrayFlat( KMmsAttributeArrayGranularity );
       
   124 
       
   125     // Set the original context to the service entry
       
   126     SwitchCurrentEntryL( iServiceId );
       
   127     }
       
   128 
       
   129 // ---------------------------------------------------------
       
   130 // CMmsClientMtm::QueryCapability
       
   131 // ---------------------------------------------------------
       
   132 //
       
   133 TInt CMmsNotificationClientMtm::QueryCapability(
       
   134     TUid /*aCapability*/,
       
   135     TInt& /*aResponse*/ )
       
   136     {
       
   137     // Nothing Supported at the moment
       
   138     return KErrNotSupported;
       
   139     }
       
   140 
       
   141 // ---------------------------------------------------------
       
   142 // CMmsNotificationClientMtm::ForwardL
       
   143 // ---------------------------------------------------------
       
   144 //
       
   145 CMsvOperation* CMmsNotificationClientMtm::ForwardL(
       
   146     TMsvId aDestination,
       
   147     TMsvPartList /*aPartList*/,
       
   148     TRequestStatus& aCompletionStatus )
       
   149     {
       
   150     //
       
   151     // Actual creation is done synchronously below
       
   152     //
       
   153     TMsvId id = CreateForwardEntryL( aDestination );
       
   154 
       
   155     //
       
   156     // This method has to be asynchronous..
       
   157     //
       
   158     TPckgC < TMsvId > progress = id;
       
   159     return  CMsvCompletedOperation::NewL( Session(), Type(), progress, 
       
   160         KMsvLocalServiceIndexEntryId, aCompletionStatus );
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------
       
   164 // CMmsClientNotificationMtm::CreateForwardEntryL
       
   165 // ---------------------------------------------------------
       
   166 //
       
   167 TMsvId CMmsNotificationClientMtm::CreateForwardEntryL( TMsvId aDestination )
       
   168     {
       
   169     //
       
   170     // Check that current context is valid
       
   171     //
       
   172     if( iMsvEntry->Entry().iType != KUidMsvMessageEntry
       
   173         || iMsvEntry->Entry().iMtm != KUidMsgMMSNotification )
       
   174         {
       
   175         User::Leave( KErrUnknown );
       
   176         }
       
   177 
       
   178     // It is assumed that a created forward entry can not be saved to drafts.
       
   179     // I.e. the application calling this, is responsible to take care that
       
   180     // the entry is either SENT or DESTROYED.
       
   181 
       
   182     //
       
   183     // Load entry to local cache if necessary
       
   184     //
       
   185     if( iMmsHeaders->ContentLocation() == TPtrC8() )
       
   186         {
       
   187         LoadMessageL();
       
   188         }
       
   189 
       
   190     //
       
   191     // Create new Mms message object into aDestination folder
       
   192     //
       
   193     TMsvId forwardId = CMmsMessageOperation::CreateForwardWithoutRetrievalL(
       
   194         Session(),
       
   195         *iMmsHeaders,
       
   196         iMsvEntry->EntryId(),
       
   197         aDestination,
       
   198         iServiceId );
       
   199 
       
   200     return forwardId;
       
   201     }
       
   202 
       
   203 // ---------------------------------------------------------
       
   204 // CMmsClientNotificationMtm::SendL
       
   205 // ---------------------------------------------------------
       
   206 //
       
   207 CMsvOperation* CMmsNotificationClientMtm::SendL( 
       
   208     TRequestStatus& aCompletionStatus,
       
   209     const TTime aSendingTime )
       
   210     {
       
   211     //
       
   212     // Is it possible to proceed with the operation...
       
   213     // If yes, the notification is marked as "further-operations-not-allowed"
       
   214     //
       
   215     TMsvId relatedNotificationId = iMmsHeaders->RelatedEntry();
       
   216     TInt retval = ReserveNotificationOperationL( relatedNotificationId, KMmsOperationForward );
       
   217     if( retval != KErrNone )
       
   218         {
       
   219         TPckgC < TMsvId > progress = relatedNotificationId;
       
   220       	return CMsvCompletedOperation::NewL(
       
   221       	    Session(),
       
   222       	    KUidMsgMMSNotification,
       
   223       	    progress, // progress contains the related entry id
       
   224       	    iServiceId,
       
   225       	    aCompletionStatus,
       
   226       	    KErrInUse);
       
   227         }
       
   228 
       
   229     //
       
   230     // Create the selection to be sent
       
   231     //
       
   232     CMsvEntrySelection* selection = new( ELeave ) CMsvEntrySelection;
       
   233     CleanupStack::PushL( selection ); // ***
       
   234     selection->AppendL( iMsvEntry->Entry().Id() );
       
   235 
       
   236     //
       
   237     // Make sure the message is in OUTBOX
       
   238     //
       
   239     TMsvId currentParent = iMsvEntry->Entry().Parent();
       
   240     if ( currentParent != KMsvGlobalOutBoxIndexEntryId )
       
   241         {
       
   242         CMsvEntry* cEntry = NULL;
       
   243         cEntry = Session().GetEntryL( currentParent );
       
   244         CleanupStack::PushL( cEntry );
       
   245         cEntry->MoveL( iMsvEntry->Entry().Id(), KMsvGlobalOutBoxIndexEntryId );
       
   246         CleanupStack::PopAndDestroy( cEntry );
       
   247         }
       
   248 
       
   249     //
       
   250     // Create parameters structure
       
   251     //
       
   252     TCommandParameters parameters;
       
   253     TTime now;
       
   254     now.UniversalTime();
       
   255     if ( aSendingTime > now )
       
   256         {
       
   257         aSendingTime.SecondsFrom( now, parameters.iInitialDelay );
       
   258         }
       
   259     TCommandParametersBuf paramPack( parameters );
       
   260 
       
   261     //
       
   262     // Call Server MTM
       
   263     //
       
   264     CMsvOperation* op = InvokeAsyncFunctionL(
       
   265         EMmsScheduledForward,
       
   266         *selection,
       
   267         paramPack,
       
   268         aCompletionStatus );
       
   269  
       
   270     //
       
   271     // Cleanup and return
       
   272     //
       
   273     CleanupStack::PopAndDestroy( selection );
       
   274     return op;
       
   275     }
       
   276 
       
   277 // ---------------------------------------------------------
       
   278 // CMmsClientNotificationMtm::SendL
       
   279 // ---------------------------------------------------------
       
   280 //
       
   281 CMsvOperation* CMmsNotificationClientMtm::SendL(
       
   282     CMsvEntrySelection& /*aSelection*/,
       
   283     TRequestStatus& /*aCompletionStatus*/,
       
   284     TTime /*aSendingTime*/ )
       
   285     {
       
   286     User::Leave( KErrNotSupported );
       
   287     return NULL; // makes the compiler happy
       
   288     }
       
   289 
       
   290 // ---------------------------------------------------------
       
   291 // CMmsClientNotificationMtm::ReserveNotificationOperationL
       
   292 // ---------------------------------------------------------
       
   293 //
       
   294 TInt CMmsNotificationClientMtm::ReserveNotificationOperationL( 
       
   295     TMsvId aNotifId,
       
   296     const TUint32 aOperation )
       
   297     {
       
   298     //
       
   299     // Get hands on index entry based on entryId
       
   300     //
       
   301     CMsvEntry* cEntry = NULL;
       
   302     cEntry = Session().GetEntryL( aNotifId );
       
   303     CleanupStack::PushL( cEntry ); // ***
       
   304     TMsvEntry tEntry = cEntry->Entry();
       
   305 
       
   306     //
       
   307     // Check that entry is a notification
       
   308     //
       
   309     if( cEntry->Entry().iType != KUidMsvMessageEntry
       
   310         || cEntry->Entry().iMtm != KUidMsgMMSNotification )
       
   311         {
       
   312         CleanupStack::PopAndDestroy( cEntry );
       
   313         return KErrNotSupported;
       
   314         }
       
   315 
       
   316     //
       
   317     // Make some checks concerning the current status of notification and
       
   318     // return with error if reservation is not possible
       
   319     //
       
   320     // if operation is forbidden OR
       
   321     // if ( (the aOperation is fetch or forward) and notification is deleted successfully from mmbox)
       
   322     if( tEntry.iMtmData2 & KMmsNewOperationForbidden ||
       
   323         ( ( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward ) &&
       
   324         tEntry.iMtmData2 & KMmsOperationFinished && 
       
   325         ! ( tEntry.iMtmData2 & KMmsOperationResult ) &&
       
   326         ! ( tEntry.iMtmData2 & KMmsStoredInMMBox ) &&
       
   327         tEntry.iMtmData2 & KMmsOperationDelete ) )
       
   328         {
       
   329         CleanupStack::PopAndDestroy( cEntry );
       
   330         return KErrInUse;        
       
   331         }
       
   332 
       
   333     //
       
   334     // Set the flags
       
   335     //
       
   336     // reserve the operation
       
   337     MarkNotificationOperationReserved( tEntry, aOperation );
       
   338     tEntry.SetReadOnly( EFalse );
       
   339 
       
   340     //
       
   341     // Save the entry
       
   342     //
       
   343     cEntry->ChangeL( tEntry );
       
   344     CleanupStack::PopAndDestroy( cEntry );
       
   345     return KErrNone;
       
   346     }
       
   347 
       
   348 // ---------------------------------------------------------
       
   349 // CMmsNotificationClientMtm::MarkFreeNotificationsReservedL
       
   350 // ---------------------------------------------------------
       
   351 //
       
   352 void CMmsNotificationClientMtm::MarkFreeNotificationsReservedL(
       
   353     CMsvEntrySelection& aNotifications, const TUint32 aOperation )
       
   354     {
       
   355     TInt count = aNotifications.Count();
       
   356     if ( count == 0 )
       
   357         {
       
   358         return;
       
   359         }
       
   360     CMsvEntry* clientEntry = Session().GetEntryL( aNotifications.At( 0 ));
       
   361     CleanupStack::PushL( clientEntry );
       
   362 
       
   363     for ( TInt i = aNotifications.Count() - 1 ; i >= 0 ; i-- ) 
       
   364         {
       
   365         TBool drop = EFalse;
       
   366         TBool alreadyMarked = EFalse;
       
   367 
       
   368         clientEntry->SetEntryL( aNotifications.At( i ) );
       
   369         TMsvEntry entry = clientEntry->Entry();
       
   370         TMsvId duplicate = KMsvNullIndexEntryId;
       
   371         if ( FreeNotification( entry, aOperation ) )
       
   372             {
       
   373             // Check possible duplicate, if mmbox folder even exists
       
   374             TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
       
   375             if ( mmboxFolder != KMsvNullIndexEntryId )
       
   376                 {
       
   377                 TMsvId parent = entry.Parent();
       
   378                 
       
   379                 CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
   380                 CleanupStack::PushL( mmsHeaders );
       
   381                 CMsvStore* store = clientEntry->ReadStoreL();
       
   382                 CleanupStack::PushL( store );
       
   383                 mmsHeaders->RestoreL( *store );
       
   384                 CleanupStack::PopAndDestroy( store );
       
   385                 store = NULL;
       
   386                 
       
   387                 if ( parent == KMsvGlobalInBoxIndexEntryId )
       
   388                     {
       
   389                     
       
   390                     FindDuplicateNotificationL( mmboxFolder, 
       
   391                         *mmsHeaders, duplicate );
       
   392                     }
       
   393                 else if ( parent == mmboxFolder )
       
   394                     {
       
   395                     FindDuplicateNotificationL( KMsvGlobalInBoxIndexEntryId, 
       
   396                         *mmsHeaders, duplicate );
       
   397                     }
       
   398                 else
       
   399                     {
       
   400                     // keep LINT happy
       
   401                     }
       
   402                 if ( duplicate != KMsvNullIndexEntryId )
       
   403                     {
       
   404                     // check if duplicate is free for a operation
       
   405                     clientEntry->SetEntryL( duplicate );
       
   406                     TMsvEntry dupEntry = clientEntry->Entry();
       
   407                     if ( FreeNotification( dupEntry, aOperation ))
       
   408                         {
       
   409                         // if original notification is in mmbox folder
       
   410                         // mark the duplicate reserved too.
       
   411                         if ( parent == mmboxFolder )
       
   412                             {
       
   413                             MarkNotificationOperationReserved( dupEntry, aOperation );
       
   414                             clientEntry->ChangeL( dupEntry );
       
   415 
       
   416                             clientEntry->SetEntryL( aNotifications.At( i ) );
       
   417                             entry = clientEntry->Entry();
       
   418                             MarkNotificationOperationReserved( entry, aOperation );
       
   419                             entry.SetReadOnly( EFalse );
       
   420                             clientEntry->ChangeL( entry );
       
   421                             alreadyMarked = ETrue;
       
   422 
       
   423                             store = clientEntry->EditStoreL();
       
   424                             CleanupStack::PushL( store );
       
   425                             mmsHeaders->RestoreL( *store );
       
   426                             mmsHeaders->SetRelatedEntry( duplicate );
       
   427                             mmsHeaders->StoreL( *store );
       
   428                             store->CommitL();
       
   429                             CleanupStack::PopAndDestroy( store );
       
   430                             store = NULL; 
       
   431                             }
       
   432                         clientEntry->SetEntryL( aNotifications.At( i ) );
       
   433                        
       
   434                         }
       
   435                     else // duplicate is not free-> original notification has to be dropped
       
   436                         {
       
   437                         drop = ETrue;
       
   438                         }
       
   439                     
       
   440                     }
       
   441                 CleanupStack::PopAndDestroy( mmsHeaders );
       
   442                 }
       
   443             
       
   444             }
       
   445         else // original notification is not free
       
   446             {
       
   447             drop = ETrue;
       
   448             }
       
   449 
       
   450         if ( drop )
       
   451             {
       
   452             // Remove the entry from selection
       
   453             aNotifications.Delete( i );
       
   454             }
       
   455         else // mark original notification reserved, unless it is already marked
       
   456             {
       
   457             if ( !alreadyMarked) 
       
   458                 {
       
   459                 clientEntry->SetEntryL( aNotifications.At( i ) );              
       
   460                 entry = clientEntry->Entry();
       
   461                 MarkNotificationOperationReserved( entry, aOperation );
       
   462                 entry.SetReadOnly( EFalse );
       
   463                 clientEntry->ChangeL( entry );
       
   464                 }   
       
   465             }
       
   466         }
       
   467     aNotifications.Compress();
       
   468 
       
   469     CleanupStack::PopAndDestroy( clientEntry );
       
   470 
       
   471     }
       
   472 
       
   473  
       
   474 // ---------------------------------------------------------
       
   475 // CMmsNotificationClientMtm::FreeNotification
       
   476 // ---------------------------------------------------------
       
   477 //       
       
   478 TBool CMmsNotificationClientMtm::FreeNotification( TMsvEntry& aEntry, const TUint32 aOperation )
       
   479     {
       
   480     if ( aEntry.iMtm != KUidMsgMMSNotification)
       
   481         {
       
   482         return EFalse;
       
   483         }
       
   484     if ( aEntry.iMtmData2 & KMmsNewOperationForbidden ||
       
   485         ( aEntry.iMtmData2 & KMmsOperationFinished &&
       
   486         !( aEntry.iMtmData2 & KMmsOperationResult ) &&
       
   487         !( aEntry.iMtmData2 & KMmsStoredInMMBox ) &&
       
   488         ( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward )))
       
   489         {
       
   490         return EFalse;
       
   491         }
       
   492 
       
   493     return ETrue;
       
   494     
       
   495     }
       
   496 
       
   497  
       
   498 // ---------------------------------------------------------
       
   499 // CMmsNotificationClientMtm::MarkNotificationOperationReserved
       
   500 // ---------------------------------------------------------
       
   501 //       
       
   502 void CMmsNotificationClientMtm::MarkNotificationOperationReserved( TMsvEntry& aEntry, 
       
   503                                                                   const TUint32 aOperation )
       
   504     {
       
   505     aEntry.iMtmData2 &= ~KMmsOperationIdentifier;   // clear possible old operation
       
   506     aEntry.iMtmData2 |= KMmsNewOperationForbidden;  // forbidden   
       
   507     aEntry.iMtmData2 |= KMmsOperationOngoing;       // operation is active
       
   508     aEntry.iMtmData2 |= aOperation;                 // operation
       
   509     aEntry.iMtmData2 &= ~KMmsOperationFinished;     // not finished
       
   510     aEntry.iMtmData2 &= ~KMmsOperationResult;       // not failed  
       
   511     }
       
   512 // ---------------------------------------------------------
       
   513 // CMmsNotificationClientMtm::FindDuplicateNotificationL
       
   514 // ---------------------------------------------------------
       
   515 // 
       
   516 void CMmsNotificationClientMtm::FindDuplicateNotificationL( TMsvId aParent, 
       
   517                                                            CMmsHeaders& aHeaders, 
       
   518                                                            TMsvId& aDuplicate )
       
   519     {
       
   520 
       
   521     aDuplicate = KMsvNullIndexEntryId;
       
   522     if ( aParent == KMsvNullIndexEntryId )
       
   523         {
       
   524         return;
       
   525         }
       
   526 
       
   527     CMsvEntry* cEntry = Session().GetEntryL( aParent );
       
   528     CleanupStack::PushL( cEntry );
       
   529 
       
   530     CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgMMSNotification );
       
   531     CleanupStack::PushL( selection );
       
   532 
       
   533     TInt count = selection->Count();
       
   534     if ( count == 0 )
       
   535         {
       
   536         CleanupStack::PopAndDestroy( selection );
       
   537         CleanupStack::PopAndDestroy( cEntry );
       
   538         return;
       
   539         }
       
   540 
       
   541     CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
   542     CleanupStack::PushL( mmsHeaders );
       
   543      
       
   544     for ( TInt i = count; i > 0 && ( aDuplicate == KMsvNullIndexEntryId ); i-- )
       
   545         {
       
   546         cEntry->SetEntryL( selection->At( i - 1 ) );
       
   547                    
       
   548         CMsvStore* store = cEntry->ReadStoreL();
       
   549         CleanupStack::PushL( store );
       
   550         mmsHeaders->RestoreL( *store );
       
   551         CleanupStack::PopAndDestroy( store );
       
   552 
       
   553         // content location must match 
       
   554         if ( mmsHeaders->ContentLocation().Compare( aHeaders.ContentLocation() ) == 0 )
       
   555             {
       
   556             aDuplicate = selection->At( i - 1 );
       
   557             }        
       
   558         }
       
   559 
       
   560     CleanupStack::PopAndDestroy( mmsHeaders );
       
   561     CleanupStack::PopAndDestroy( selection );
       
   562     CleanupStack::PopAndDestroy( cEntry );
       
   563     }
       
   564     
       
   565 // ---------------------------------------------------------
       
   566 // CMmsClientNotificationMtm::GetExtendedText
       
   567 // ---------------------------------------------------------
       
   568 //
       
   569 const TPtrC CMmsNotificationClientMtm::GetExtendedText() const
       
   570     {
       
   571     return iMmsHeaders->ExtendedNotification();
       
   572     }
       
   573 
       
   574 // ---------------------------------------------------------
       
   575 // CMmsNotificationClientMtm::FetchMessagesL
       
   576 // ---------------------------------------------------------
       
   577 //
       
   578 CMsvOperation* CMmsNotificationClientMtm::FetchMessagesL( 
       
   579     const CMsvEntrySelection& aSelection,
       
   580     TRequestStatus& aCompletionStatus )
       
   581     {
       
   582     if ( aSelection.Count() == 0 )
       
   583         {
       
   584         User::Leave( KErrNotFound );
       
   585         }
       
   586 
       
   587     CMsvEntrySelection* notifications = aSelection.CopyLC();
       
   588   
       
   589      // mark free notifications reserved. Others are dropped out.
       
   590     MarkFreeNotificationsReservedL( *notifications, KMmsOperationFetch );
       
   591 
       
   592     // check if none of the entries are allowed to start fetch
       
   593     if ( notifications->Count() == 0 )
       
   594         {
       
   595         // leave will destroy reserved items from cleanupstack
       
   596         User::Leave( KErrNotSupported );
       
   597         }
       
   598 
       
   599     TCommandParameters parameters; // initialized to zero
       
   600     TCommandParametersBuf paramPack( parameters );
       
   601 
       
   602     // Fetch messages
       
   603     CMsvOperation* op = InvokeAsyncFunctionL(
       
   604         EMmsScheduledReceiveForced,
       
   605         *notifications,
       
   606         paramPack,
       
   607         aCompletionStatus ); 
       
   608 
       
   609     CleanupStack::PopAndDestroy( notifications );
       
   610     return op;
       
   611     }
       
   612 
       
   613 // ---------------------------------------------------------
       
   614 // CMmsNotificationClientMtm::FetchMessageL
       
   615 // ---------------------------------------------------------
       
   616 //
       
   617 CMsvOperation* CMmsNotificationClientMtm::FetchMessageL( 
       
   618     TMsvId aUid, 
       
   619     TRequestStatus& aCompletionStatus )
       
   620     {
       
   621     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
       
   622     CleanupStack::PushL( selection );
       
   623     selection->AppendL( aUid );
       
   624 
       
   625     // Mark the notification reserved for fetching is possible
       
   626     MarkFreeNotificationsReservedL( *selection, KMmsOperationFetch );
       
   627 
       
   628     // if notification is not allowed to be fetched, 
       
   629     // the notification is dropped from selection. 
       
   630     if ( selection->Count() == 0 )
       
   631         {
       
   632         CleanupStack::PopAndDestroy( selection );
       
   633         return NULL;
       
   634         }
       
   635 
       
   636     TCommandParameters parameters; // initialized to zero
       
   637     TCommandParametersBuf paramPack( parameters );
       
   638 
       
   639     // Fetch the message
       
   640     CMsvOperation* op = InvokeAsyncFunctionL(
       
   641         EMmsScheduledReceiveForced,
       
   642         *selection,
       
   643         paramPack,
       
   644         aCompletionStatus ); 
       
   645 
       
   646     CleanupStack::PopAndDestroy( selection );
       
   647     return op;
       
   648     }
       
   649 
       
   650 // ---------------------------------------------------------
       
   651 // CMmsNotificationClientMtm::FetchAllL
       
   652 // ---------------------------------------------------------
       
   653 //
       
   654 
       
   655 CMsvOperation* CMmsNotificationClientMtm::FetchAllL( TRequestStatus& aCompletionStatus,
       
   656     TBool aForced )
       
   657     {
       
   658     // List notifications that have no active operation
       
   659     CMsvEntrySelection* notifications = ListNotificationsL();
       
   660     if ( notifications->Count() == 0 )
       
   661         {
       
   662         delete notifications;
       
   663         notifications = NULL;
       
   664         User::Leave( KErrNotFound );
       
   665         }
       
   666     CleanupStack::PushL( notifications );
       
   667    
       
   668     // Loop through the notifications and reserve them for the operation
       
   669     TInt retval = KErrNone;
       
   670     TInt count = notifications->Count();
       
   671     for ( TInt i = count; i > 0; i-- ) 
       
   672         {
       
   673         retval = ReserveNotificationOperationL( notifications->At( i - 1 ), KMmsOperationFetch );
       
   674         if( retval != KErrNone )
       
   675             {
       
   676             // Remove the entry from selection
       
   677             notifications->Delete( i - 1 );
       
   678             } 
       
   679         }
       
   680 
       
   681     TCommandParameters parameters; // initialized to zero
       
   682     TCommandParametersBuf paramPack( parameters );
       
   683 
       
   684     // Fetch the message
       
   685     CMsvOperation* op = NULL;
       
   686     if ( aForced )
       
   687         {
       
   688         op = InvokeAsyncFunctionL(
       
   689             EMmsScheduledReceiveForced,
       
   690             *notifications,
       
   691             paramPack,
       
   692             aCompletionStatus ); 
       
   693         }
       
   694     else
       
   695         {
       
   696         op = InvokeAsyncFunctionL(
       
   697             EMmsScheduledReceive,
       
   698             *notifications,
       
   699             paramPack,
       
   700             aCompletionStatus ); 
       
   701         }
       
   702 
       
   703     CleanupStack::PopAndDestroy( notifications );
       
   704     return op;
       
   705     }
       
   706 
       
   707 // ---------------------------------------------------------
       
   708 // CMmsNotificationClientMtm::NotificationCount
       
   709 // ---------------------------------------------------------
       
   710 //
       
   711 TInt CMmsNotificationClientMtm::NotificationCount()
       
   712     {
       
   713     TInt numberOfNotifications = -1;
       
   714 
       
   715     TInt error = KErrNone;
       
   716     CMsvEntrySelection* notifications = NULL;
       
   717 
       
   718     TRAP( error, 
       
   719         { notifications = ListNotificationsL();
       
   720         });
       
   721         
       
   722     if ( error == KErrNone )
       
   723         {
       
   724         numberOfNotifications = notifications->Count();
       
   725         }
       
   726         
       
   727     delete notifications;
       
   728     notifications = NULL;    
       
   729     
       
   730     return numberOfNotifications;
       
   731     }
       
   732 
       
   733 // ---------------------------------------------------------
       
   734 // CMmsNotificationClientMtm::ListNotificationsL
       
   735 // ---------------------------------------------------------
       
   736 //
       
   737 CMsvEntrySelection* CMmsNotificationClientMtm::ListNotificationsL()
       
   738     {
       
   739     return CMmsClientMtm::ListNotificationsInInboxL();
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------
       
   743 // CMmsNotificationClientMtm::DeleteNotificationL
       
   744 // ---------------------------------------------------------
       
   745 //
       
   746 CMsvOperation* CMmsNotificationClientMtm::DeleteNotificationL( 
       
   747     const CMsvEntrySelection& aSelection,
       
   748     TMmsDeleteOperationType aDeleteType,
       
   749     TRequestStatus& aCompletionStatus )
       
   750     {
       
   751     
       
   752     if ( aSelection.Count() == 0 )
       
   753         {
       
   754         // if nothing to delete, operation is complete
       
   755         TPckgC < TMsvId > progress = 0;
       
   756         return  CMsvCompletedOperation::NewL( Session(), Type(), progress, 
       
   757             KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
       
   758         }
       
   759     
       
   760     //
       
   761     // aDeleteType has to be delivered to server side.
       
   762     // Using TCommandParameters.iError for it on purpose.
       
   763     //
       
   764     TCommandParameters parameters;
       
   765     parameters.iError = aDeleteType;
       
   766     TCommandParametersBuf paramPack( parameters );
       
   767 
       
   768     //
       
   769     // Modifying indexentries
       
   770     //
       
   771     CMsvEntry* cEntry = NULL;
       
   772     cEntry = Session().GetEntryL( aSelection.At( 0 ) );
       
   773     CleanupStack::PushL( cEntry ); // ***
       
   774     for ( TInt i = 0; i < aSelection.Count(); i++ ) 
       
   775         {
       
   776         cEntry->SetEntryL( aSelection.At( i ) );
       
   777         TMsvEntry tEntry = cEntry->Entry();
       
   778         tEntry.SetReadOnly( EFalse );
       
   779         cEntry->ChangeL( tEntry );
       
   780         }
       
   781     CleanupStack::PopAndDestroy( cEntry );
       
   782 
       
   783     //
       
   784     // NOTE: Notification delete operations perform majority of the work in
       
   785     // the server side. This includes also notification reservation for the operation.
       
   786     //
       
   787 
       
   788     //
       
   789     // Calling server side
       
   790     //
       
   791     CMsvOperation* op = InvokeAsyncFunctionL(
       
   792         EMmsScheduledNotificationDelete,
       
   793         aSelection,
       
   794         paramPack,
       
   795         aCompletionStatus ); 
       
   796     return op;
       
   797     }
       
   798 
       
   799 // ---------------------------------------------------------
       
   800 // CMmsNotificationClientMtm::UnscheduledDeleteNotificationL
       
   801 // ---------------------------------------------------------
       
   802 //
       
   803 CMsvOperation* CMmsNotificationClientMtm::UnscheduledDeleteNotificationL( 
       
   804     const CMsvEntrySelection& aSelection,
       
   805     TMmsDeleteOperationType aDeleteType,
       
   806     TRequestStatus& aCompletionStatus )
       
   807     {
       
   808     
       
   809     if ( aSelection.Count() == 0 )
       
   810        {
       
   811         // if nothing to delete, operation is complete
       
   812         TPckgC < TMsvId > progress = 0;
       
   813         return  CMsvCompletedOperation::NewL( Session(), Type(), progress, 
       
   814             KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
       
   815         }
       
   816     
       
   817     //
       
   818     // aDeleteType has to be delivered to server side.
       
   819     // Using TCommandParameters.iError for it on purpose.
       
   820     //
       
   821     TCommandParameters parameters;
       
   822     parameters.iError = aDeleteType;
       
   823     TCommandParametersBuf paramPack( parameters );
       
   824 
       
   825     //
       
   826     // NOTE: Notification delete operations perform majority of the work in
       
   827     // the server side. This includes also notification reservation for the operation.
       
   828     //
       
   829 
       
   830     //
       
   831     // Calling server side
       
   832     //
       
   833     CMsvOperation* op = InvokeAsyncFunctionL(
       
   834         EMmsNotificationDelete,
       
   835         aSelection,
       
   836         paramPack,
       
   837         aCompletionStatus ); 
       
   838     return op;
       
   839     }
       
   840 
       
   841 // ---------------------------------------------------------
       
   842 // CMmsNotificationClientMtm::DeleteAllNotificationsL
       
   843 // ---------------------------------------------------------
       
   844 //
       
   845 CMsvOperation* CMmsNotificationClientMtm::DeleteAllNotificationsL( 
       
   846     TMmsDeleteOperationType aDeleteType,
       
   847     TRequestStatus& aCompletionStatus )
       
   848     {
       
   849     //
       
   850     // Get selection of all the notifications in Inbox
       
   851     // (operations that do not have ongoing operations)
       
   852     // 
       
   853     CMsvEntrySelection* selection = ListNotificationsL();
       
   854     
       
   855     if ( selection->Count() == 0 )
       
   856         {
       
   857         delete selection;
       
   858         selection = NULL;
       
   859         // if nothing to delete, operation is complete
       
   860         TPckgC < TMsvId > progress = 0;
       
   861         return  CMsvCompletedOperation::NewL( Session(), Type(), progress, 
       
   862             KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
       
   863         }
       
   864     
       
   865     CleanupStack::PushL( selection );
       
   866 
       
   867     //
       
   868     // Call DeleteNotificationL with the selection just created
       
   869     //
       
   870     CMsvOperation* op = DeleteNotificationL( 
       
   871         *selection, 
       
   872         aDeleteType, 
       
   873         aCompletionStatus );
       
   874     CleanupStack::PopAndDestroy( selection );
       
   875     return op;
       
   876     }
       
   877 
       
   878 // ---------------------------------------------------------
       
   879 // CMmsNotificationClientMtm::DeleteForwardEntryL
       
   880 // ---------------------------------------------------------
       
   881 //
       
   882 void CMmsNotificationClientMtm::DeleteForwardEntryL( const CMsvEntrySelection& aSelection )
       
   883     {
       
   884     //
       
   885     // Loop through the selection of forward entries
       
   886     //
       
   887     TInt count = aSelection.Count();
       
   888     for( TInt index = 0; index < count; index++ )
       
   889         {
       
   890         iMsvEntry->SetEntryL( aSelection.At( index ) );
       
   891         TMsvEntry tEntry = iMsvEntry->Entry();
       
   892         // Test entry type
       
   893         if( tEntry.iType != KUidMsvMessageEntry ||
       
   894             tEntry.iMtm != KUidMsgMMSNotification ||
       
   895             !( tEntry.iMtmData1 & KMmsMessageForwardReq ) )
       
   896             {
       
   897             continue;
       
   898             }
       
   899         // Test entry location
       
   900         TMsvId parentId = tEntry.Parent();
       
   901         if( ( parentId != KMsvGlobalOutBoxIndexEntryId ) &&
       
   902             ( parentId != KMsvSentEntryId ) )
       
   903             {
       
   904             continue;
       
   905             }
       
   906         // Test that entry is not in a middle of some other action
       
   907         if( tEntry.SendingState() == KMsvSendStateSending )
       
   908             {
       
   909             // Too late to delete
       
   910             continue;
       
   911             }
       
   912         else
       
   913             {
       
   914             // Quickly "reserve" the entry for deletion
       
   915             tEntry.SetSendingState( KMsvSendStateSuspended );
       
   916             iMsvEntry->ChangeL( tEntry );
       
   917             }
       
   918         //
       
   919         // Entry will do; it will be deleted.
       
   920         //
       
   921 
       
   922         // But first clearing possible related notification
       
   923         CMsvStore* store = iMsvEntry->ReadStoreL();
       
   924         CleanupStack::PushL( store ); // ***
       
   925         CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
   926         CleanupStack::PushL( mmsHeaders );
       
   927         mmsHeaders->RestoreL( *store );
       
   928         TMsvId relatedId = mmsHeaders->RelatedEntry();
       
   929         CleanupStack::PopAndDestroy( mmsHeaders );
       
   930         CleanupStack::PopAndDestroy( store );
       
   931 
       
   932         // If forward entry has a "related id" (i.e. id of the notification),
       
   933         // context is changed to it and it will be cleared.
       
   934         if( relatedId != KMsvNullIndexEntryId )
       
   935             {
       
   936             // Change to related notification
       
   937             iMsvEntry->SetEntryL( relatedId );
       
   938             tEntry = iMsvEntry->Entry();
       
   939             // "Clear" the flags
       
   940             tEntry.iMtmData2 &= ~KMmsOperationIdentifier;   // clear possible old operations
       
   941             tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // not forbidden
       
   942             tEntry.iMtmData2 &= ~KMmsOperationOngoing;      // not ongoing
       
   943             tEntry.iMtmData2 &= ~KMmsOperationFinished;     // not finished (this is notification's initial state)
       
   944             tEntry.iMtmData2 &= ~KMmsOperationResult;       // clear also the result flag ("assuming OK")
       
   945             tEntry.SetReadOnly( ETrue );
       
   946             iMsvEntry->ChangeL( tEntry );
       
   947             }
       
   948 
       
   949         // Activating parent entry of the forward entry
       
   950         iMsvEntry->SetEntryL( parentId );
       
   951         // Delete forward entry
       
   952         iMsvEntry->DeleteL( aSelection.At( index ) );
       
   953         } // for loop
       
   954     }
       
   955 
       
   956 // ---------------------------------------------------------
       
   957 // CMmsNotificationClientMtm::MmboxInfoL
       
   958 // ---------------------------------------------------------
       
   959 //
       
   960 TBool CMmsNotificationClientMtm::MmboxInfoL( TMmboxInfo& aMmboxInfo )
       
   961     {
       
   962     // check first, if quota information is available.
       
   963     TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
       
   964     CMsvEntry* cEntry = Session().GetEntryL( KMsvLocalServiceIndexEntryId );
       
   965     CleanupStack::PushL( cEntry );
       
   966     TInt pushedToStack = 1;
       
   967 
       
   968     cEntry->SetEntryL( mmboxFolder );
       
   969     // Show invisible entries
       
   970     cEntry->SetSortTypeL( TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByIdReverse, ETrue ) );
       
   971     CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgTypeMultimedia );
       
   972     CleanupStack::PushL( selection );
       
   973     pushedToStack++;
       
   974 
       
   975     TBool quotaInfoAvailable = EFalse;
       
   976 
       
   977     if ( selection->Count() > 0 )
       
   978         {                
       
   979         cEntry->SetEntryL( selection->At( 0 ));
       
   980         CMsvStore* store = cEntry->ReadStoreL();
       
   981         CleanupStack::PushL( store );
       
   982         pushedToStack++;
       
   983         CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
   984         CleanupStack::PushL( mmsHeaders );
       
   985         pushedToStack++;
       
   986         mmsHeaders->RestoreL( *store );
       
   987         
       
   988         // Get quota info
       
   989         CMmsMMBoxViewHeaders& viewHeaders = mmsHeaders->MMBoxViewHeadersL();
       
   990 
       
   991         aMmboxInfo.mmboxTotalInBytes = viewHeaders.MMBoxTotalSize();
       
   992         aMmboxInfo.mmboxTotalInMessageCount = viewHeaders.MMBoxTotalNumber();
       
   993         aMmboxInfo.mmboxQuotaInBytes = viewHeaders.MMBoxQuotaSize();
       
   994         aMmboxInfo.mmboxQuotaInMessageCount = viewHeaders.MMBoxQuotaNumber();
       
   995 
       
   996         // get Date info
       
   997         TMsvEntry tEntry = cEntry->Entry();
       
   998         aMmboxInfo.date = tEntry.iDate;
       
   999         
       
  1000         // error
       
  1001         aMmboxInfo.error = tEntry.iError;
       
  1002         
       
  1003         quotaInfoAvailable = ETrue;
       
  1004         }
       
  1005 
       
  1006     CleanupStack::PopAndDestroy( pushedToStack );
       
  1007     return quotaInfoAvailable;
       
  1008     }
       
  1009 // ---------------------------------------------------------
       
  1010 // CMmsNotificationClientMtm::UpdateMmBoxListL
       
  1011 // ---------------------------------------------------------
       
  1012 //
       
  1013 CMsvOperation* CMmsNotificationClientMtm::UpdateMmBoxListL(
       
  1014             TRequestStatus& aCompletionStatus )
       
  1015     {
       
  1016     TCommandParameters parameters; // initialized to zero
       
  1017     TCommandParametersBuf paramPack( parameters );
       
  1018 
       
  1019     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
       
  1020     CleanupStack::PushL( selection ); 
       
  1021     selection->AppendL( iServiceId );
       
  1022 
       
  1023     // Update mmbox list
       
  1024     CMsvOperation* op = InvokeAsyncFunctionL(
       
  1025         EMmsUpdateMmboxList,
       
  1026         *selection,
       
  1027         paramPack,
       
  1028         aCompletionStatus ); 
       
  1029 
       
  1030     CleanupStack::PopAndDestroy( selection );
       
  1031     return op;
       
  1032     }
       
  1033 
       
  1034 // ---------------------------------------------------------
       
  1035 // CMmsNotificationClientMtm::GetMmboxFolderL
       
  1036 // ---------------------------------------------------------
       
  1037 //
       
  1038 TMsvId CMmsNotificationClientMtm::GetMmboxFolderL()
       
  1039     {
       
  1040     return iMmsSettings->MMBoxFolder();
       
  1041     }
       
  1042    
       
  1043 // ---------------------------------------------------------
       
  1044 // CMmsNotificationClientMtm
       
  1045 // ---------------------------------------------------------
       
  1046 //
       
  1047 const TPtrC CMmsNotificationClientMtm::GetApplicationId() const
       
  1048     {
       
  1049     return iMmsHeaders->ApplicId();
       
  1050     }
       
  1051 
       
  1052 // ================= OTHER EXPORTED FUNCTIONS ==============
       
  1053 
       
  1054 //  End of File  
       
  1055 
       
  1056