messagingapp/msgnotifications/msgnotifier/src/msgstorehandler.cpp
changeset 25 84d9eb65b26f
child 34 84197e66a4bd
child 37 518b245aa84c
equal deleted inserted replaced
23:238255e8b033 25:84d9eb65b26f
       
     1 /*
       
     2  * Copyright (c) 2008 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:  Message Store Handling for Indications
       
    15  *
       
    16  */
       
    17 
       
    18 #include "msgstorehandler.h"
       
    19 #include "s60qconversions.h"
       
    20 #include "msgnotifier_p.h"
       
    21 #include <ccsrequesthandler.h>
       
    22 #include <ccsconversationentry.h>
       
    23 #include <ccsclientconversation.h>
       
    24 
       
    25 #include <msvids.h>
       
    26 #include <mmsconst.h>
       
    27 #include <SendUiConsts.h>
       
    28 #include <msvsearchsortquery.h>
       
    29 #include <msvsearchsortoperation.h>
       
    30 
       
    31 // CONSTANTS
       
    32 
       
    33 // ================= MEMBER FUNCTIONS =======================
       
    34 
       
    35 // ---------------------------------------------------------
       
    36 // Default constructor.
       
    37 // ---------------------------------------------------------
       
    38 //
       
    39 MsgStoreHandler::MsgStoreHandler(MsgNotifierPrivate* notifier, CCSRequestHandler* aCvServer) :
       
    40     iMsvSession(NULL), iNotifier(notifier), iRequestHandler(aCvServer)
       
    41 {
       
    42     TRAP_IGNORE(InitL());
       
    43 }
       
    44 
       
    45 // ---------------------------------------------------------
       
    46 // Destructor.
       
    47 // ---------------------------------------------------------
       
    48 //
       
    49 MsgStoreHandler::~MsgStoreHandler()
       
    50 {
       
    51     if (iMsvEntry) {
       
    52         delete iMsvEntry;
       
    53         iMsvEntry = NULL;
       
    54     }
       
    55 
       
    56     if (iMsvSession) {
       
    57         delete iMsvSession;
       
    58         iMsvSession = NULL;
       
    59     }
       
    60 
       
    61     if (iFailedMessages) {
       
    62         delete iFailedMessages;
       
    63         iFailedMessages = NULL;
       
    64     }
       
    65 
       
    66     if (iFailedNotes) {
       
    67         delete iFailedNotes;
       
    68         iFailedNotes = NULL;
       
    69     }
       
    70 }
       
    71 
       
    72 // ---------------------------------------------------------
       
    73 // InitL( )
       
    74 // Initialize the Store handler.
       
    75 // ---------------------------------------------------------
       
    76 void MsgStoreHandler::InitL()
       
    77 {
       
    78     iMsvSession = CMsvSession::OpenSyncL(*this);
       
    79     iMsvEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
    80     iMsvEntry->AddObserverL(*this);
       
    81 
       
    82     iFailedMessages = new (ELeave) CMsvEntrySelection;
       
    83     iFailedNotes = new (ELeave) CMsvEntrySelection;
       
    84 }
       
    85 
       
    86 // ---------------------------------------------------------
       
    87 // MsgStoreHandler::HandleSessionEventL()
       
    88 // ---------------------------------------------------------
       
    89 //
       
    90 void MsgStoreHandler::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
       
    91 {
       
    92     CMsvEntrySelection* selection = NULL;
       
    93     TMsvId parent;
       
    94 
       
    95     //args
       
    96     if (aArg1 == NULL || aArg2 == NULL) {
       
    97         return;
       
    98     }
       
    99 
       
   100     //start, processing the event
       
   101     selection = (CMsvEntrySelection*) aArg1;
       
   102     parent = *(TMsvId*) aArg2;
       
   103 
       
   104     // Return when not (outbox or inbox) and  event not EMsvEntriesChanged
       
   105     if (!(parent == KMsvGlobalOutBoxIndexEntryIdValue || parent == KMsvGlobalInBoxIndexEntryIdValue)
       
   106         && aEvent != EMsvEntriesChanged) {
       
   107         return;
       
   108     }
       
   109 
       
   110     //Handling for outbox entries
       
   111     if( parent == KMsvGlobalOutBoxIndexEntryIdValue )
       
   112     {
       
   113         CMsvEntry* rootEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   114 
       
   115         for (TInt i = 0; i < selection->Count(); ++i) {
       
   116             TMsvEntry entry = rootEntry->ChildDataL(selection->At(i));
       
   117 
       
   118             if ((entry.iMtm == KSenduiMtmSmsUid) || (entry.iMtm == KSenduiMtmMmsUid)) {
       
   119                 TUint sendingState = entry.SendingState();
       
   120                 TInt index = iFailedMessages->Find(entry.Id());
       
   121 
       
   122                 if (sendingState == KMsvSendStateFailed && KErrNotFound == index) {
       
   123                     iFailedMessages->AppendL(entry.Id());
       
   124                     iFailedNotes->AppendL(entry.Id());
       
   125                 }
       
   126                 else if (sendingState != KMsvSendStateFailed && KErrNotFound != index) {
       
   127                     iFailedMessages->Delete(index);
       
   128                     iFailedMessages->Compress();
       
   129                 }
       
   130                 if (iFailedNotes->Count()) {
       
   131                     MsgInfo aInfo;
       
   132                     ProcessIndicatorDataL(iFailedNotes->At(0), aInfo);
       
   133                     iNotifier->displayFailedNote(aInfo);
       
   134                     iFailedNotes->Delete(0);
       
   135                     iFailedNotes->Compress();
       
   136                 }
       
   137             }
       
   138         }//end for
       
   139     }
       
   140     else
       
   141     {
       
   142         TMsvEntry entry;
       
   143         TMsvId service;
       
   144         TInt error= KErrNone;
       
   145         for (TInt i = 0; i < selection->Count(); ++i)
       
   146         {
       
   147             error = iMsvSession->GetEntry(selection->At(i), service, entry);
       
   148 
       
   149             if (error == KErrNone && entry.iMtm == KUidMsgMMSNotification && MmsNotificationStatus(
       
   150                 entry) == EMsgStatusFailed)
       
   151             {
       
   152                 MsgInfo aInfo;
       
   153                                 
       
   154                 //Fill aInfo with appropriate data
       
   155                 aInfo.mMessageType = ECsMmsNotification;
       
   156 
       
   157                 ProcessIndicatorDataL(entry.Id(),aInfo);
       
   158                 iNotifier->displayFailedNote(aInfo);
       
   159             }
       
   160         }
       
   161     }
       
   162 }
       
   163 
       
   164 // ---------------------------------------------------------
       
   165 // MsgStoreHandler::HandleEntryEventL()
       
   166 // ---------------------------------------------------------
       
   167 
       
   168 void MsgStoreHandler::HandleEntryEventL(TMsvEntryEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/,
       
   169     TAny* /*aArg3*/)
       
   170 {
       
   171     switch (aEvent) {
       
   172     case EMsvChildrenChanged:
       
   173     case EMsvDeletedChildren:
       
   174     {
       
   175         UpdateOutboxIndications();
       
   176         break;
       
   177     }
       
   178     default:
       
   179         break;
       
   180 
       
   181     }
       
   182 }
       
   183 
       
   184 // ---------------------------------------------------------
       
   185 // UpdateOutboxIndications()
       
   186 // Outgoing Pending message/messages
       
   187 // ---------------------------------------------------------
       
   188 void MsgStoreHandler::UpdateOutboxIndications()
       
   189 {
       
   190     MsgInfo failedIndicatorData;
       
   191     MsgInfo pendingIndicatorData;
       
   192 
       
   193     TInt err = KErrNone;
       
   194 
       
   195     TRAP(err, GetOutboxEntriesL(failedIndicatorData, pendingIndicatorData));
       
   196 
       
   197     if (err == KErrNone) {
       
   198         iNotifier->displayOutboxIndications(failedIndicatorData);
       
   199         iNotifier->displayOutboxIndications(pendingIndicatorData);
       
   200     }
       
   201 }
       
   202 
       
   203 // ---------------------------------------------------------
       
   204 // GetOutboxEntries()
       
   205 // Outgoing Pending message/messages
       
   206 // ---------------------------------------------------------
       
   207 TInt MsgStoreHandler::GetOutboxEntriesL(MsgInfo& aFailedIndicatorData,
       
   208     MsgInfo& aPendingIndicatorData)
       
   209 {
       
   210     CMsvEntry* rootEntry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   211     CMsvEntrySelection* messages = rootEntry->ChildrenL();
       
   212 
       
   213     TInt failedMessageCount = 0;
       
   214     TInt pendingMessageCount = 0;
       
   215 
       
   216     for (TInt i = 0; i < messages->Count(); ++i) {
       
   217         TMsvEntry entry = rootEntry->ChildDataL(messages->At(i));
       
   218         if ((entry.iMtm != KSenduiMtmSmsUid) && (entry.iMtm != KSenduiMtmMmsUid)) {
       
   219             continue;
       
   220         }
       
   221 
       
   222         if (entry.SendingState() == KMsvSendStateFailed) {
       
   223             ++failedMessageCount;
       
   224         }
       
   225         else {
       
   226             ++pendingMessageCount;
       
   227         }
       
   228 
       
   229         if (entry.SendingState() == KMsvSendStateFailed) {
       
   230             ProcessIndicatorDataL(entry.Id(), aFailedIndicatorData);
       
   231         }
       
   232         else {
       
   233             ProcessIndicatorDataL(entry.Id(), aPendingIndicatorData);
       
   234         }
       
   235        
       
   236     }
       
   237 
       
   238     aFailedIndicatorData.mFromSingle = (failedMessageCount > 1) ? false : true;
       
   239     aPendingIndicatorData.mFromSingle = (pendingMessageCount > 1) ? false : true;
       
   240     aFailedIndicatorData.mIndicatorType = FailedIndicatorPlugin;
       
   241     aPendingIndicatorData.mIndicatorType = PendingIndicatorPlugin;
       
   242     aFailedIndicatorData.mMsgCount = failedMessageCount;
       
   243     aPendingIndicatorData.mMsgCount = pendingMessageCount;
       
   244 
       
   245     return KErrNone;
       
   246 }
       
   247 
       
   248 // ---------------------------------------------------------
       
   249 // ProcessIndicatorData()
       
   250 // Process the data in the MsgInfo object. 
       
   251 // ---------------------------------------------------------
       
   252 
       
   253 void MsgStoreHandler::ProcessIndicatorDataL(TMsvId msgId, MsgInfo& indicatorData)
       
   254 {
       
   255     CCsClientConversation* conversation = iRequestHandler->GetConversationFromMessageIdL(msgId);
       
   256     if (conversation == NULL)
       
   257         return;
       
   258 
       
   259     indicatorData.mConversationId = conversation->GetConversationEntryId();
       
   260     CCsConversationEntry* convEntry = conversation->GetConversationEntry();
       
   261 
       
   262     //check for valid data
       
   263     if ((indicatorData.mConversationId == -1) || (convEntry == NULL)) {
       
   264         delete conversation;
       
   265         return;
       
   266     }
       
   267     
       
   268     //set indicator data
       
   269     HBufC* displayName = conversation->GetDisplayName();
       
   270 
       
   271     if (displayName) {
       
   272         indicatorData.mDisplayName.append(S60QConversions::s60DescToQString(*displayName));
       
   273     }
       
   274     else {
       
   275         HBufC* number = convEntry->Contact();
       
   276         if (number)
       
   277             indicatorData.mDisplayName.append(S60QConversions::s60DescToQString(*number));
       
   278     }
       
   279     delete conversation;
       
   280 }
       
   281 
       
   282 // ---------------------------------------------------------
       
   283 // GetUnreadMessageCountL()
       
   284 // Get Unread message count.
       
   285 // ---------------------------------------------------------
       
   286 
       
   287 int MsgStoreHandler::GetUnreadMessageCountL()
       
   288 {
       
   289     //Create  the query/operation object
       
   290     CMsvSearchSortOperation *operation = CMsvSearchSortOperation::NewL(*iMsvSession);
       
   291     CleanupStack::PushL(operation);
       
   292     CMsvSearchSortQuery *query = CMsvSearchSortQuery::NewL();
       
   293     CleanupStack::PushL(query);
       
   294 
       
   295     //set the query options
       
   296     query->SetParentId(KMsvGlobalInBoxIndexEntryId);
       
   297     query->SetResultType(EMsvResultAsTMsvEntry);
       
   298     query->AddSearchOptionL(EMsvUnreadMessages, ETrue);
       
   299     CleanupStack::Pop(query);
       
   300 
       
   301     CMsvOperationWait* wait = CMsvOperationWait::NewLC();
       
   302     //ownership of Query transferred to Operation  
       
   303     operation->RequestL(query, EFalse, wait->iStatus);
       
   304     wait->Start();
       
   305     CActiveScheduler::Start();
       
   306 
       
   307     //Get No of entries
       
   308     int count = operation->GetResultCountL();
       
   309     CleanupStack::PopAndDestroy(2, operation);
       
   310 
       
   311     return count;
       
   312 }
       
   313 
       
   314 // ---------------------------------------------------------
       
   315 // MsgStoreHandler::MmsNotificationStatus
       
   316 // ---------------------------------------------------------
       
   317 //
       
   318 TCsMmsNotificationMsgState MsgStoreHandler::
       
   319 MmsNotificationStatus( TMsvEntry entry )
       
   320     {   
       
   321     TCsMmsNotificationMsgState status = EMsgStatusNull;
       
   322 
       
   323     // operationMask includes operation type. It is not bitmap but ordinal number. 
       
   324     // It does not include operation status and result
       
   325     TInt operationMask = (entry.iMtmData2 & KMmsOperationIdentifier) ;
       
   326 
       
   327     // Note! Ongoing operation resets every bit of operation type, operation status
       
   328     // and result. E.g. If message has been forwarded and then fetching starts, 
       
   329     // information about forwarding is lost
       
   330 
       
   331     if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd )
       
   332         {
       
   333         if(     operationMask == KMmsOperationFetch 
       
   334                 &&  OperationOngoing( entry ) )
       
   335             { 
       
   336             // It's in retrieving state
       
   337             status = EMsgStatusRetrieving;
       
   338             }
       
   339         else if(    operationMask == KMmsOperationForward
       
   340                 &&  OperationOngoing( entry ) )
       
   341             { 
       
   342             // It's in forwarding state
       
   343             status = EMsgStatusForwarding;
       
   344             }
       
   345         else if(    operationMask == KMmsOperationForward
       
   346                 &&  OperationFinished( entry )
       
   347                 &&  !( entry.iMtmData2 & KMmsOperationResult ) )
       
   348             { 
       
   349             // It's been forwarded succesfully
       
   350             status = EMsgStatusForwarded;
       
   351             }
       
   352         else if(    operationMask == KMmsOperationFetch 
       
   353                 &&  OperationFinished( entry )
       
   354                 &&   (  entry.iMtmData2 & KMmsOperationResult 
       
   355                 ||  entry.iError ) )
       
   356             { 
       
   357             // Fetch has been failed
       
   358             status = EMsgStatusFailed;
       
   359             }
       
   360         else if(    operationMask == KMmsOperationDelete
       
   361                 &&  OperationFinished( entry )
       
   362                 &&  !( entry.iMtmData2 & KMmsOperationResult ) )
       
   363             { 
       
   364             // It's been deleted succesfully
       
   365             status = EMsgStatusDeleted;
       
   366             }
       
   367         else 
       
   368             {   // Normal waiting state
       
   369             status = EMsgStatusReadyForFetching;
       
   370             }
       
   371         }
       
   372 
       
   373     return status;
       
   374     }
       
   375 
       
   376 // ---------------------------------------------------------
       
   377 // MsgStoreHandler::OperationOngoing
       
   378 // ---------------------------------------------------------
       
   379 //
       
   380 TBool MsgStoreHandler::OperationOngoing( const TMsvEntry& aEntry ) const
       
   381     {
       
   382     return (    aEntry.iMtmData2 & KMmsOperationOngoing 
       
   383             &&  !( aEntry.iMtmData2 & KMmsOperationFinished ) );
       
   384     }
       
   385 
       
   386 // ---------------------------------------------------------
       
   387 // ConversationMsgStoreHandler::OperationFinished
       
   388 // ---------------------------------------------------------
       
   389 //
       
   390 TBool MsgStoreHandler::OperationFinished( 
       
   391     const TMsvEntry& aEntry ) const
       
   392     {
       
   393     return (    aEntry.iMtmData2 & KMmsOperationFinished
       
   394             &&  !( aEntry.iMtmData2 & KMmsOperationOngoing ) );
       
   395     }
       
   396 
       
   397 // End of file