pushmtm/Plugins/PushContentHandler/CSLContentHandler.cpp
changeset 51 48e827313edd
parent 37 481242ead638
child 53 f427d27b98d8
equal deleted inserted replaced
37:481242ead638 51:48e827313edd
     1 /*
       
     2 * Copyright (c) 2002 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 the License "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:  Implementation of CSLContentHandler.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 
       
    22 #include "CSLContentHandler.h"
       
    23 #include "PushMtmUtil.h"
       
    24 #include "PushMtmSettings.h"
       
    25 #include "PushAuthenticationUtilities.h"
       
    26 #include "PushMtmLog.h"
       
    27 #include "PushContentHandlerPanic.h"
       
    28 #include "PushMtmAutoFetchOperation.h"
       
    29 #include "PushMtmUiDef.h"
       
    30 #include "StringResourceReader.h"
       
    31 #include "sl_dict.h"
       
    32 #include "PushContentHandlerUtils.h"
       
    33 #include <push/cslpushmsgentry.h>
       
    34 #include <msvids.h>
       
    35 #include <apgtask.h>
       
    36 #include <apgcli.h>
       
    37 #include <w32std.h>
       
    38 #include <PushMtmUi.rsg>
       
    39 #include <nw_dom_node.h>
       
    40 #include <nw_dom_document.h>
       
    41 #include <nw_dom_element.h>
       
    42 #include <nw_dom_text.h>
       
    43 #include <nw_wbxml_dictionary.h>
       
    44 #include <nw_string_char.h>
       
    45 
       
    46 // CONSTANTS
       
    47 
       
    48 // sl attributes / elements
       
    49 _LIT8( KSl,      "sl" );
       
    50 _LIT8( KHref,    "href" );
       
    51 _LIT8( KAction,  "action" );
       
    52 
       
    53 // action attribute literals
       
    54 _LIT8( KExecHigh,"execute-high" );  
       
    55 _LIT8( KExecLow, "execute-low" );
       
    56 _LIT8( KCache,   "cache" );
       
    57 
       
    58 // Text SL MIME type
       
    59 _LIT( KSlTextContentType, "text/vnd.wap.sl" );
       
    60 
       
    61 // Browser command to fetch an URL. See Browser API Specification!
       
    62 _LIT( KBrowserCmdFetchUrl, "4 " );
       
    63 const TUid KBrowserAppUid = { 0x10008D39 };
       
    64 
       
    65 const TInt KNoOfDictArrays = 1;
       
    66 
       
    67 /// Autofetch time delay in seconds.
       
    68 const TInt KAutofetchDelayInSec = 5;
       
    69 
       
    70 // file monitored by browser
       
    71 _LIT( KPushMtmUrl, "c:\\system\\temp\\PushMtmUrl.txt" );
       
    72 
       
    73 // ================= MEMBER FUNCTIONS =======================
       
    74 
       
    75 // ---------------------------------------------------------
       
    76 // CSLContentHandler::NewL
       
    77 // ---------------------------------------------------------
       
    78 //
       
    79 CSLContentHandler* CSLContentHandler::NewL()
       
    80 	{
       
    81 	CSLContentHandler* self = new (ELeave) CSLContentHandler;
       
    82 	CleanupStack::PushL( self );
       
    83 	self->ConstructL();
       
    84 	CleanupStack::Pop( self );
       
    85 	return self;
       
    86 	}
       
    87 
       
    88 // ---------------------------------------------------------
       
    89 // CSLContentHandler::~CSLContentHandler
       
    90 // ---------------------------------------------------------
       
    91 //
       
    92 CSLContentHandler::~CSLContentHandler()
       
    93 	{
       
    94     PUSHLOG_ENTERFN("CSLContentHandler::~CSLContentHandler")
       
    95 
       
    96     Cancel();
       
    97     delete iFetchOp;
       
    98     delete iHrefBuf;
       
    99 
       
   100     PUSHLOG_LEAVEFN("CSLContentHandler::~CSLContentHandler")
       
   101     }
       
   102 
       
   103 // ---------------------------------------------------------
       
   104 // CSLContentHandler::CSLContentHandler
       
   105 // ---------------------------------------------------------
       
   106 //
       
   107 CSLContentHandler::CSLContentHandler()
       
   108 :   CPushContentHandlerBase(), 
       
   109     iSavedMsgId( KMsvNullIndexEntryId ), 
       
   110     iPushMsgAction( KErrNotFound ), 
       
   111     iSaveAsRead( EFalse )
       
   112 	{
       
   113 	}
       
   114 
       
   115 // ---------------------------------------------------------
       
   116 // CSLContentHandler::ConstructL
       
   117 // ---------------------------------------------------------
       
   118 //
       
   119 void CSLContentHandler::ConstructL()
       
   120 	{
       
   121     PUSHLOG_ENTERFN("CSLContentHandler::ConstructL")
       
   122 
       
   123     CPushContentHandlerBase::ConstructL();
       
   124     // Added to Active Scheduler.
       
   125 
       
   126     PUSHLOG_LEAVEFN("CSLContentHandler::ConstructL")
       
   127     }
       
   128 
       
   129 // ---------------------------------------------------------
       
   130 // CSLContentHandler::CollectGarbageL
       
   131 // ---------------------------------------------------------
       
   132 //
       
   133 void CSLContentHandler::CollectGarbageL()
       
   134 	{
       
   135     PUSHLOG_ENTERFN("CSLContentHandler::CollectGarbageL")
       
   136 
       
   137     DoCollectGarbageL();
       
   138 
       
   139 #ifdef __SERIES60_PUSH_SL
       
   140 	iState = EFilteringAndParsing;
       
   141 #else // __SERIES60_PUSH_SL
       
   142     // Do nothing - message is discarded.
       
   143 	iState = EDone;
       
   144 #endif // __SERIES60_PUSH_SL
       
   145 	IdleComplete();
       
   146 
       
   147     PUSHLOG_LEAVEFN("CSLContentHandler::CollectGarbageL")
       
   148     }
       
   149 
       
   150 #ifdef __SERIES60_PUSH_SL
       
   151 
       
   152 // ---------------------------------------------------------
       
   153 // CSLContentHandler::ParsePushMsgL
       
   154 // Note that cXML parser dosn't do any validation!
       
   155 // ---------------------------------------------------------
       
   156 //
       
   157 void CSLContentHandler::ParsePushMsgL()
       
   158 	{
       
   159     PUSHLOG_ENTERFN("CSLContentHandler::ParsePushMsgL")
       
   160 
       
   161     TPtrC8 bodyPtr;
       
   162     iMessage->GetMessageBody( bodyPtr );
       
   163     // If there is no body in the message leave with an error
       
   164     if ( bodyPtr.Size() == 0 )
       
   165         {
       
   166         PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: Empty body")
       
   167         User::Leave( KErrCorrupt );
       
   168         }
       
   169 
       
   170     TPtrC contentType;
       
   171     iMessage->GetContentType( contentType );
       
   172     PUSHLOG_WRITE_FORMAT(" Content type <%S>",&contentType)
       
   173 
       
   174     // Add SL dictionary.
       
   175     NW_WBXML_Dictionary_t* dictArray[ KNoOfDictArrays ] = 
       
   176         { (NW_WBXML_Dictionary_t*)&NW_SL_WBXMLDictionary };
       
   177 
       
   178     NW_Status_t stat = NW_STAT_SUCCESS;
       
   179 
       
   180     RWbxmlDictionary wbxmlDict;
       
   181     wbxmlDict.InitializeL( KNoOfDictArrays, dictArray );
       
   182     CleanupClosePushL<RWbxmlDictionary>( wbxmlDict );
       
   183 
       
   184     NW_TinyDom_Handle_t domHandle;
       
   185     NW_Byte* buffer = (NW_Byte*)bodyPtr.Ptr();
       
   186     NW_Int32 length = (NW_Int32)bodyPtr.Size();
       
   187     NW_Bool encoded = ( contentType.CompareF( KSlTextContentType ) == 0 ) ? 
       
   188                                                          NW_FALSE : NW_TRUE;
       
   189     NW_Uint32 publicID = NW_SL_PublicId;
       
   190     NW_Bool extTNotStringTable = NW_FALSE; // What is this?
       
   191     NW_DOM_NodeType_t type = 0;
       
   192     /**********************************
       
   193     *   Root of DOM
       
   194     ***********************************/
       
   195     CDocumentTreeOwner* docTreeOwner = new (ELeave) CDocumentTreeOwner;
       
   196     CleanupStack::PushL( docTreeOwner );
       
   197     NW_DOM_DocumentNode_t* domNode = NW_DOM_DocumentNode_BuildTree
       
   198         ( 
       
   199                             &domHandle, 
       
   200                             buffer, 
       
   201                             length, 
       
   202                             encoded, 
       
   203                             publicID, 
       
   204                             extTNotStringTable 
       
   205         );
       
   206 	if (!domNode)
       
   207 		{
       
   208 		PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: domNode is Null")
       
   209 		}
       
   210     User::LeaveIfNull( domNode );
       
   211     docTreeOwner->SetDocTree( domNode );
       
   212 
       
   213     type = NW_DOM_Node_getNodeType( domNode );
       
   214     if ( type != NW_DOM_DOCUMENT_NODE )
       
   215         {
       
   216         PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not Document node <%d>",type)
       
   217         User::Leave( KErrArgument );
       
   218         }
       
   219 
       
   220     iCharEncoding = NW_DOM_DocumentNode_getCharacterEncoding( domNode );
       
   221     PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Doc char encoding <%x>",iCharEncoding)
       
   222 
       
   223     /**********************************
       
   224     *   ELEMENT sl
       
   225     ***********************************/
       
   226 	// first make sure if there any children in the dom tree, otherwise we will PANIC(in NW_DOM_DocumentNode_getDocumentElement) and crash WatcherMainThread.
       
   227 	TBool domNodeHasChildNodes = EFalse;
       
   228 	domNodeHasChildNodes = NW_DOM_Node_hasChildNodes( domNode );
       
   229 	PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: check if Dom tree has <SI> node <%d>", domNodeHasChildNodes)
       
   230 	if (!domNodeHasChildNodes)
       
   231         {
       
   232         PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: No SL element present in the dom tree. Message corrupted.")
       
   233         User::Leave( KErrCorrupt );
       
   234         }
       
   235 
       
   236 	PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: before calling getDocumentElement")
       
   237     NW_DOM_ElementNode_t* slElement = 
       
   238         NW_DOM_DocumentNode_getDocumentElement( domNode );
       
   239 	if (!slElement)
       
   240 		{
       
   241 		PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: slElement is Null")
       
   242 		}
       
   243     User::LeaveIfNull( slElement );
       
   244 
       
   245     type = NW_DOM_Node_getNodeType( slElement );
       
   246 
       
   247     CStringOwner* stringOwner = new (ELeave) CStringOwner;
       
   248     CleanupStack::PushL( stringOwner );
       
   249 
       
   250     NW_String_t* name = NW_String_new();
       
   251     User::LeaveIfNull( name );
       
   252     stringOwner->SetString( name );
       
   253     stat = NW_DOM_Node_getNodeName( slElement, name );
       
   254 	PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getNodeName ErrCode: %d", NwxStatusToErrCode( stat ))
       
   255     User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   256     NW_Byte*  nameBuf = NW_String_getStorage( name );
       
   257     NW_Uint16 nameLen = NW_String_getCharCount( name, iCharEncoding );
       
   258     TPtrC8 namePtr( nameBuf, nameLen );
       
   259 
       
   260     if ( type != NW_DOM_ELEMENT_NODE || namePtr.CompareF( KSl ) != 0 )
       
   261         {
       
   262         PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not sl element node <%d>",type)
       
   263         User::Leave( KErrArgument );
       
   264         }
       
   265 
       
   266     CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
       
   267 
       
   268     /**********************************
       
   269     *   Attributes of ELEMENT sl
       
   270     ***********************************/
       
   271     if ( NW_DOM_ElementNode_hasAttributes( slElement ) )
       
   272         {
       
   273         NW_DOM_AttributeListIterator_t attrIter;
       
   274         stat = NW_DOM_ElementNode_getAttributeListIterator
       
   275                              ( slElement, &attrIter );
       
   276 		PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getAttribListIter ErrCode: %d", NwxStatusToErrCode( stat ))
       
   277         User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   278 
       
   279         NW_DOM_AttributeHandle_t attrHandle;
       
   280         while( NW_DOM_AttributeListIterator_getNextAttribute
       
   281                ( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
       
   282             {
       
   283             ParseSlAttributeL( attrHandle );
       
   284             }
       
   285         }
       
   286 
       
   287     // Cleanup.
       
   288     CleanupStack::PopAndDestroy( 2, &wbxmlDict ); // docTreeOwner, wbxmlDict
       
   289 
       
   290     // if 'action' attribute not specified, the value 'execute-low' is used.
       
   291 	if ( !ActionFlag() )
       
   292         {
       
   293 		iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   294         SetActionFlag( ETrue );
       
   295         PUSHLOG_WRITE_FORMAT(" Defaulting to ActionFlag: %d",iPushMsgAction)
       
   296         }
       
   297 
       
   298     iState = EProcessing;
       
   299     IdleComplete();
       
   300 
       
   301     PUSHLOG_LEAVEFN("CSLContentHandler::ParsePushMsgL")
       
   302 	}
       
   303 
       
   304 // ---------------------------------------------------------
       
   305 // CSLContentHandler::ParseSlAttributeL
       
   306 // ---------------------------------------------------------
       
   307 //
       
   308 void CSLContentHandler::ParseSlAttributeL
       
   309                         ( NW_DOM_AttributeHandle_t& aAttrHandle )
       
   310 	{
       
   311     PUSHLOG_ENTERFN("CSLContentHandler::ParseSlAttributeL")
       
   312 
       
   313     NW_Status_t stat = NW_STAT_SUCCESS;
       
   314 
       
   315     CStringOwner* attrNameOwner = new (ELeave) CStringOwner;
       
   316     CleanupStack::PushL( attrNameOwner );
       
   317 
       
   318     NW_String_t* attrName = NW_String_new();
       
   319     User::LeaveIfNull( attrName );
       
   320     attrNameOwner->SetString( attrName );
       
   321 
       
   322     // Get the name of the attribute.
       
   323     stat = NW_DOM_AttributeHandle_getName( &aAttrHandle, attrName );
       
   324     User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   325     NW_Byte*  attrNameBuf = NW_String_getStorage( attrName );
       
   326     NW_Uint16 attrNameLen = NW_String_getCharCount( attrName, iCharEncoding );
       
   327     TPtrC8 attrNamePtr( attrNameBuf, attrNameLen );
       
   328 
       
   329     if ( attrNamePtr.CompareF( KHref ) == 0 )
       
   330         {
       
   331         if ( !HrefFlag() )
       
   332             {
       
   333             HBufC* tempHrefBuf = NULL;
       
   334 
       
   335             CStringOwner* valOwner = new (ELeave) CStringOwner;
       
   336             CleanupStack::PushL( valOwner );
       
   337 
       
   338             NW_String_t* val = NW_String_new();
       
   339             User::LeaveIfNull( val );
       
   340             valOwner->SetString( val );
       
   341             stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
       
   342             if ( stat != NW_STAT_DOM_NO_STRING_RETURNED )
       
   343                 {
       
   344                 User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   345                 NW_Byte* storage = NW_String_getStorage( val );
       
   346                 NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
       
   347                 TPtrC8 prefixPtr( storage, length );
       
   348                 tempHrefBuf = HBufC::NewMaxL( length );
       
   349                 // No leavable after it!!! until...
       
   350                 tempHrefBuf->Des().Copy( prefixPtr );
       
   351                 }
       
   352 
       
   353             CleanupStack::PopAndDestroy( valOwner ); // valOwner
       
   354 
       
   355             if ( tempHrefBuf )
       
   356                 {
       
   357                 if ( tempHrefBuf->Length() == 0 )
       
   358                     {
       
   359                     // Zero length Href is considered as nothing.
       
   360                     PUSHLOG_WRITE(" Zero length HrefFlag");
       
   361                     }
       
   362                 else
       
   363                     {
       
   364                     iHrefBuf = tempHrefBuf; // ...until here.
       
   365                     SetHrefFlag( ETrue );
       
   366                     PUSHLOG_WRITE_FORMAT(" HrefFlag set <%S>",iHrefBuf);
       
   367                     }
       
   368                 }
       
   369             }
       
   370         }
       
   371     else if ( attrNamePtr.CompareF( KAction ) == 0 )
       
   372         {
       
   373         if ( !ActionFlag() )
       
   374             {
       
   375             CStringOwner* stringOwner = new (ELeave) CStringOwner;
       
   376             CleanupStack::PushL( stringOwner );
       
   377 
       
   378             NW_String_t* val = NW_String_new();
       
   379             User::LeaveIfNull( val );
       
   380             stringOwner->SetString( val );
       
   381             stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val ); 
       
   382             User::LeaveIfError( NwxStatusToErrCode( stat ) );
       
   383             NW_Byte* storage = NW_String_getStorage( val );
       
   384             NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
       
   385             TPtrC8 actionPtr( storage, length );
       
   386 
       
   387             iPushMsgAction = ConvertActionString( actionPtr );
       
   388             SetActionFlag( ETrue );
       
   389             PUSHLOG_WRITE_FORMAT(" ActionFlag: %d",iPushMsgAction)
       
   390 
       
   391             CleanupStack::PopAndDestroy( stringOwner );
       
   392             }
       
   393         }
       
   394     else
       
   395         {
       
   396         __ASSERT_DEBUG( EFalse, 
       
   397             ContHandPanic( EPushContHandPanUnexpSlToken ) );
       
   398         }
       
   399 
       
   400     CleanupStack::PopAndDestroy( attrNameOwner ); // attrNameOwner
       
   401 
       
   402     PUSHLOG_LEAVEFN("CSLContentHandler::ParseSlAttributeL")
       
   403     }
       
   404 
       
   405 // ---------------------------------------------------------
       
   406 // CSLContentHandler::ConvertActionString
       
   407 // ---------------------------------------------------------
       
   408 //
       
   409 TUint CSLContentHandler::ConvertActionString
       
   410                          ( const TDesC8& aActionString ) const
       
   411 	{
       
   412 	const TInt KMatchFound = 0;
       
   413 
       
   414 	// if 'action' attribute not specified, the value 'execute-low' is used.
       
   415 	TUint actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   416 
       
   417 	if ( aActionString.Compare( KExecHigh ) == KMatchFound )
       
   418         {
       
   419 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteHigh;
       
   420         }
       
   421 	else if ( aActionString.Compare( KExecLow ) == KMatchFound )
       
   422         {
       
   423 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
       
   424         }
       
   425 	else if ( aActionString.Compare( KCache ) == KMatchFound )
       
   426         {
       
   427 		actionValue = CSLPushMsgEntry::ESLPushMsgExecuteCache;
       
   428         }
       
   429 
       
   430 	return actionValue;
       
   431 	}
       
   432 
       
   433 // ---------------------------------------------------------
       
   434 // CSLContentHandler::SetSlPushMsgEntryFieldsL
       
   435 // ---------------------------------------------------------
       
   436 //
       
   437 void CSLContentHandler::SetSlPushMsgEntryFieldsL( CSLPushMsgEntry& 
       
   438                                                   aSlPushMsgEntry ) const
       
   439 	{
       
   440     PUSHLOG_ENTERFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
       
   441 
       
   442 	// Set URL and Action fields.
       
   443     if ( HrefFlag() )
       
   444         {
       
   445 	    aSlPushMsgEntry.SetUrlL( *iHrefBuf );
       
   446         }
       
   447 
       
   448     __ASSERT_DEBUG( ActionFlag(), 
       
   449                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   450     if ( ActionFlag() )
       
   451         {
       
   452 	    aSlPushMsgEntry.SetAction( iPushMsgAction );
       
   453         }
       
   454     else // if not specified, the value 'execute-low' is used.
       
   455         {
       
   456         aSlPushMsgEntry.SetAction( CSLPushMsgEntry::ESLPushMsgExecuteLow );
       
   457         }
       
   458 
       
   459 	// Set all the relevant header fields.
       
   460 	TPtrC8 msgHeaderPtr;
       
   461 	iMessage->GetHeader( msgHeaderPtr );
       
   462 	aSlPushMsgEntry.SetHeaderL( msgHeaderPtr );
       
   463 
       
   464     // Get server address.
       
   465     TPtrC8 srvAddress;
       
   466     if ( iMessage->GetServerAddress( srvAddress ) )
       
   467         {
       
   468 	    aSlPushMsgEntry.SetFromL( srvAddress );
       
   469         }
       
   470 
       
   471     // First line in Inbox: TMsvEntry::iDetails.
       
   472     if ( srvAddress.Length() == 0 )
       
   473         {
       
   474         // Read from resource.
       
   475         HBufC* details = 
       
   476             iStrRscReader->AllocReadResourceLC( R_PUSHMISC_UNK_SENDER );
       
   477         aSlPushMsgEntry.SetMsgDetailsL( *details );
       
   478         CleanupStack::PopAndDestroy( details );
       
   479         }
       
   480     else
       
   481         {
       
   482         // Convert the "From" information to the format required by the UI 
       
   483         // spec and then decode it.
       
   484         HBufC* details = iWapPushUtils->ConvertDetailsL( srvAddress );
       
   485         CleanupStack::PushL( details );
       
   486         HBufC* convertedFrom = 
       
   487             CPushMtmUtil::ConvertUriToDisplayFormL( *details );
       
   488         CleanupStack::PushL( convertedFrom );
       
   489         //
       
   490         aSlPushMsgEntry.SetMsgDetailsL( *convertedFrom );
       
   491         //
       
   492         CleanupStack::PopAndDestroy( 2, details ); // convertedFrom, details
       
   493         }
       
   494 
       
   495     // Second line in Inbox: TMsvEntry::iDescription.
       
   496     // Read from resource.
       
   497     HBufC* description = 
       
   498         iStrRscReader->AllocReadResourceLC( R_PUSHMISC_INBOX_SERV_MSG );
       
   499     aSlPushMsgEntry.SetMsgDescriptionL( *description );
       
   500     CleanupStack::PopAndDestroy( description );
       
   501 
       
   502     // ******** Push MTM specific processing *********
       
   503 
       
   504     /*
       
   505     * Unfortunately in CPushMsgEntryBase there is no such functionality 
       
   506     * with which we can reach TMsvEntry as non-const, but we have to 
       
   507     * modify the entry's iMtmData2 member somehow. We can do it 
       
   508     * with either casting or with modifying and saving the entry 
       
   509     * manually after it has been saved by CSLPushMsgEntry. The latter 
       
   510     * solution is more expensive so we choose the first.
       
   511     */
       
   512     TMsvEntry& tEntry = CONST_CAST( TMsvEntry&, aSlPushMsgEntry.Entry() );
       
   513     if ( HrefFlag() )
       
   514         {
       
   515         CPushMtmUtil::SetAttrs( tEntry, EPushMtmAttrHasHref );
       
   516         }
       
   517     else
       
   518         {
       
   519         CPushMtmUtil::ResetAttrs( tEntry, EPushMtmAttrHasHref );
       
   520         }
       
   521 
       
   522     // Indication is required if the entry is saved as 'read' (delete & 
       
   523     // replacement notification). It can happen only in case of SL message.
       
   524     // Otherwise the flag has to be cleared!
       
   525     if ( !iSaveAsRead )
       
   526         {
       
   527         // Saving as unread & new.
       
   528         tEntry.SetNew( ETrue );
       
   529         tEntry.SetUnread( ETrue );
       
   530         CPushMtmUtil::ResetAttrs( tEntry, EPushMtmReadButContentChanged );
       
   531         }
       
   532     else
       
   533         {
       
   534         // Saving as read.
       
   535         tEntry.SetNew( EFalse );
       
   536         tEntry.SetUnread( EFalse );
       
   537         CPushMtmUtil::SetAttrs( tEntry, EPushMtmReadButContentChanged );
       
   538         }
       
   539 
       
   540     PUSHLOG_LEAVEFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
       
   541     }
       
   542 
       
   543 // ---------------------------------------------------------
       
   544 // CSLContentHandler::ProcessingPushMsgEntryL
       
   545 // ---------------------------------------------------------
       
   546 //
       
   547 void CSLContentHandler::ProcessingPushMsgEntryL()
       
   548 	{
       
   549     PUSHLOG_ENTERFN("CSLContentHandler::ProcessingPushMsgEntryL")
       
   550 
       
   551     TBool discardPushMsg( EFalse );
       
   552 
       
   553     __ASSERT_DEBUG( ActionFlag(), 
       
   554                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   555 
       
   556     // S60 requirement: if the href is empty then delete (discard) the msg.
       
   557     if ( HrefFlag() == EFalse )
       
   558         {
       
   559         PUSHLOG_WRITE(" No SL Href.")
       
   560         discardPushMsg = ETrue;
       
   561         }
       
   562     else
       
   563         {
       
   564         __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   565                         ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   566 
       
   567         // The message will not be discarded
       
   568         discardPushMsg = EFalse;
       
   569 
       
   570         CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
       
   571                                               ( *iHrefBuf, KUidWapPushMsgSL );
       
   572         TInt matchingListCount = matchingUrlList->Count();
       
   573         PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
       
   574 
       
   575         // Only one SL is allowed with the same Url, so leave the first and 
       
   576         // delete the others.
       
   577         if ( 1 < matchingListCount )
       
   578             {
       
   579             for ( TInt count = 1; count < matchingListCount; ++count )
       
   580                 {
       
   581                 iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
       
   582                 }
       
   583             matchingListCount = 1; // Only one remains.
       
   584             }
       
   585 
       
   586 	    if ( 0 < matchingListCount )
       
   587 		    {
       
   588 		    // Find msg of the same href and discard it if it has a lower or 
       
   589             // the same action value.
       
   590             CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
       
   591 	        CleanupStack::PushL( matchingSl );
       
   592 
       
   593             const TMsvId matchingId = matchingUrlList->At(0);
       
   594             matchingSl->RetrieveL( *iMsvSession, matchingId );
       
   595 
       
   596             if ( iPushMsgAction <= matchingSl->Action() ) 
       
   597 			    {
       
   598                 PUSHLOG_WRITE(" SL: not higher action")
       
   599                 discardPushMsg = ETrue;
       
   600                 }
       
   601 
       
   602             CleanupStack::PopAndDestroy( matchingSl ); // matchingSl, 
       
   603             }
       
   604 
       
   605 	    CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
       
   606         }
       
   607 
       
   608     if ( discardPushMsg )
       
   609         {
       
   610         // Nothing to do.
       
   611         PUSHLOG_WRITE(" SL discarded.")
       
   612         iState = EDone;
       
   613         IdleComplete();
       
   614         }
       
   615     else
       
   616         {
       
   617         iState = HandleServiceInvocationL();
       
   618         IdleComplete();
       
   619         }
       
   620 
       
   621     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   622                     ContHandPanic( EPushContHandPanSlMsgIdSet ) );
       
   623 
       
   624     PUSHLOG_LEAVEFN("CSLContentHandler::ProcessingPushMsgEntryL")
       
   625 	}
       
   626 
       
   627 // ---------------------------------------------------------
       
   628 // CSLContentHandler::HandleServiceInvocationL
       
   629 // ---------------------------------------------------------
       
   630 //
       
   631 TInt CSLContentHandler::HandleServiceInvocationL() const
       
   632     {
       
   633     PUSHLOG_ENTERFN("CSLContentHandler::HandleServiceInvocationL")
       
   634 
       
   635     TInt nextState = ESavePushMsgEntry;
       
   636 
       
   637     if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
       
   638         {
       
   639         PUSHLOG_WRITE(" SL cache");
       
   640         TBool isAuthenticated = TPushAuthenticationUtil::
       
   641             AuthenticateMsgL( *iMtmSettings, *iMessage );
       
   642 		if ( !isAuthenticated )
       
   643             {
       
   644             PUSHLOG_WRITE(" Not authenticated");
       
   645             // The message is placed to Inbox.
       
   646             nextState = ESavePushMsgEntry;
       
   647             }
       
   648         else
       
   649             {
       
   650             // Authenticated. Fetch SL-cache.
       
   651             nextState = EFetching;
       
   652             }
       
   653         }
       
   654 
       
   655     else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteLow )
       
   656         {
       
   657         PUSHLOG_WRITE(" SL execute-low")
       
   658         // It is independent from Automatic/Manual setting and WL 
       
   659         // authentication is not applied. The message is placed to Inbox 
       
   660         // for manual downloading.
       
   661         nextState = ESavePushMsgEntry;
       
   662         }
       
   663 
       
   664     else // ESLPushMsgExecuteHigh
       
   665         {
       
   666         PUSHLOG_WRITE(" SL execute-high");
       
   667         // If the settings is Manual or it does not pass the WL authentication 
       
   668 		// then it is placed to Inbox for manual downloading.
       
   669         // If the setting is Automatic and it passes the WL authentication, 
       
   670         // the Browser is started standalone to download the URL without any 
       
   671 		// user interaction.
       
   672         if ( iMtmSettings->ServiceLoadingType() == 
       
   673 			               CPushMtmSettings::EManual )
       
   674             {
       
   675             PUSHLOG_WRITE(" Manual setting")
       
   676             // The message is placed to Inbox.
       
   677             nextState = ESavePushMsgEntry;
       
   678             }
       
   679         else // Automatic loading
       
   680             {
       
   681             PUSHLOG_WRITE(" Automatic setting");
       
   682             // Authenticate the message.
       
   683             TBool isAuthenticated = TPushAuthenticationUtil::
       
   684                 AuthenticateMsgL( *iMtmSettings, *iMessage );
       
   685             if ( !isAuthenticated )
       
   686 	            {
       
   687                 PUSHLOG_WRITE(" Not authenticated");
       
   688 	            // The message is placed to Inbox.
       
   689 	            nextState = ESavePushMsgEntry;
       
   690 	            }
       
   691             else
       
   692 	            {
       
   693 	            // Authenticated - start downloading.
       
   694 	            nextState = EFetching;
       
   695 	            }
       
   696             }
       
   697         }
       
   698 
       
   699     PUSHLOG_LEAVEFN("CSLContentHandler::HandleServiceInvocationL")
       
   700     return nextState;
       
   701     }
       
   702 
       
   703 // ---------------------------------------------------------
       
   704 // CSLContentHandler::FetchPushMsgEntryL
       
   705 // ---------------------------------------------------------
       
   706 //
       
   707 void CSLContentHandler::FetchPushMsgEntryL()
       
   708 	{
       
   709     PUSHLOG_ENTERFN("CSLContentHandler::FetchPushMsgEntryL")
       
   710 
       
   711     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   712                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   713     __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   714                     ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   715 
       
   716     /* 
       
   717     * In case of execute-high use the Browser to download the service.
       
   718     * In case of cache use the fetch operation to download the service 
       
   719     * silently. 
       
   720     */
       
   721 
       
   722     if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteHigh )
       
   723         {
       
   724         PUSHLOG_WRITE(" Start Browser")
       
   725         // Launch the Browser with the URI, then save the message.
       
   726         // Trap errors. If Browser's launching fails, then save the 
       
   727         // message as 'unread'. In case of an error, it is not forwarded.
       
   728         TRAPD( err, StartBrowserL() );
       
   729         iState = ESavePushMsgEntry;
       
   730         // Mark it 'read' after succesfull Browser startup.
       
   731         iSaveAsRead = err ? EFalse : ETrue;
       
   732         IdleComplete();
       
   733         }
       
   734     else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
       
   735         {
       
   736         // Fetch the service inside the content handler.
       
   737         iStatus = KRequestPending;
       
   738         SetActive();
       
   739         __ASSERT_DEBUG( !iFetchOp, 
       
   740                         ContHandPanic( EPushContHandPanFetchAlreadyInit ) );
       
   741 
       
   742         iFetchOp = CPushMtmAutoFetchOperation::NewL( *iHrefBuf, 
       
   743                                                      KAutofetchDelayInSec, 
       
   744                                                      iStatus );
       
   745         iFetchOp->StartL();
       
   746         PUSHLOG_WRITE(" Fetch op started")
       
   747         iState = EFetchCompleted; // Next state.
       
   748         // Fetch completes it.
       
   749         }
       
   750     else
       
   751         {
       
   752         __ASSERT_DEBUG( EFalse, 
       
   753                         ContHandPanic( EPushContHandPanBadActionValue ) );
       
   754         User::Leave( KErrNotSupported );
       
   755         }
       
   756 
       
   757     PUSHLOG_LEAVEFN("CSLContentHandler::FetchPushMsgEntryL")
       
   758     }
       
   759 
       
   760 // ---------------------------------------------------------
       
   761 // CSLContentHandler::StartBrowserL
       
   762 // ---------------------------------------------------------
       
   763 //
       
   764 void CSLContentHandler::StartBrowserL()
       
   765     {
       
   766     PUSHLOG_ENTERFN("CSLContentHandler::StartBrowserL")
       
   767 
       
   768     // Parameters are separated by space
       
   769     // 1st parameter: type of the further parameters
       
   770     // 2nd parameter: URL
       
   771     //
       
   772     HBufC* param = HBufC::NewLC( KBrowserCmdFetchUrl().Length() + 
       
   773                                  iHrefBuf->Length() );
       
   774     TPtr paramPtr = param->Des();
       
   775     paramPtr.Copy( KBrowserCmdFetchUrl );
       
   776     paramPtr.Append( *iHrefBuf );
       
   777 
       
   778     RWsSession wsSession;
       
   779     User::LeaveIfError( wsSession.Connect() );
       
   780     CleanupClosePushL<RWsSession>( wsSession );
       
   781     TApaTaskList taskList( wsSession );
       
   782     TApaTask task = taskList.FindApp( KBrowserAppUid );
       
   783 
       
   784     if ( task.Exists() )
       
   785         {
       
   786         PUSHLOG_WRITE("CSLContentHandler Browser::SendMessage")
       
   787 
       
   788         RFs             rfs;
       
   789         RFile           file;
       
   790         TPtrC8          param8Ptr;
       
   791         // 8-bit buffer is required.
       
   792         HBufC8* param8 = HBufC8::NewLC( param->Length() );
       
   793         param8->Des().Copy( *param );
       
   794         param8Ptr.Set(param8->Des());
       
   795 
       
   796         // Open the file.
       
   797         User::LeaveIfError(rfs.Connect());
       
   798         CleanupClosePushL(rfs);
       
   799 
       
   800         // Replace file if exists or Create file if not exist yet
       
   801         User::LeaveIfError( file.Replace( rfs, KPushMtmUrl, EFileWrite | EFileShareExclusive ) );
       
   802         CleanupClosePushL(file);
       
   803 
       
   804         // Write to file      
       
   805         User::LeaveIfError( file.Write( param8Ptr ) );
       
   806         
       
   807         // Clean up.
       
   808         CleanupStack::PopAndDestroy(/*file*/);
       
   809         CleanupStack::PopAndDestroy(/*rfs*/);
       
   810         CleanupStack::PopAndDestroy( /*param8*/ );
       
   811         }
       
   812     else 
       
   813         {
       
   814         PUSHLOG_WRITE("CSLContentHandler Browser::StartDocument")
       
   815         RApaLsSession appArcSession;
       
   816         User::LeaveIfError( appArcSession.Connect() );
       
   817         CleanupClosePushL<RApaLsSession>( appArcSession );
       
   818         TThreadId id;
       
   819         User::LeaveIfError
       
   820             (
       
   821                 appArcSession.StartDocument( *param, KBrowserAppUid, id )
       
   822             );
       
   823         CleanupStack::PopAndDestroy( &appArcSession );
       
   824         }
       
   825 
       
   826     CleanupStack::PopAndDestroy( &wsSession );
       
   827     CleanupStack::PopAndDestroy( param );
       
   828 
       
   829     PUSHLOG_LEAVEFN("CSLContentHandler::StartBrowserL")
       
   830     }
       
   831 
       
   832 // ---------------------------------------------------------
       
   833 // CSLContentHandler::FetchCompletedL
       
   834 // ---------------------------------------------------------
       
   835 //
       
   836 void CSLContentHandler::FetchCompletedL()
       
   837 	{
       
   838     PUSHLOG_ENTERFN("CSLContentHandler::FetchCompletedL")
       
   839 
       
   840     __ASSERT_DEBUG( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache, 
       
   841                     ContHandPanic( EPushContHandPanBadActionValue ) );
       
   842     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   843                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   844     __ASSERT_DEBUG( iFetchOp, ContHandPanic( EPushContHandPanNoFetchOp ) );
       
   845 
       
   846     const TInt fetchRes = iStatus.Int();
       
   847     PUSHLOG_WRITE_FORMAT(" fetchRes <%d>",fetchRes)
       
   848 
       
   849     if ( fetchRes != KErrNone )
       
   850         {
       
   851         // Downloading failed. Save the message.
       
   852         iState = ESavePushMsgEntry;
       
   853         }
       
   854     else
       
   855         {
       
   856         // Silent fetching has completed successfully.
       
   857         // The message should not be saved.
       
   858         iState = EDone;
       
   859         }
       
   860 
       
   861     // Next state set. Complete.
       
   862     IdleComplete();
       
   863 
       
   864     PUSHLOG_LEAVEFN("CSLContentHandler::FetchCompletedL")
       
   865     }
       
   866 
       
   867 // ---------------------------------------------------------
       
   868 // CSLContentHandler::SavePushMsgEntryL
       
   869 // ---------------------------------------------------------
       
   870 //
       
   871 void CSLContentHandler::SavePushMsgEntryL()
       
   872     {
       
   873     PUSHLOG_ENTERFN("CSLContentHandler::SavePushMsgEntryL")
       
   874 
       
   875     __ASSERT_DEBUG( ActionFlag(), 
       
   876                     ContHandPanic( EPushContHandPanUnspecSlAction ) );
       
   877     __ASSERT_DEBUG( HrefFlag() && iHrefBuf, 
       
   878                     ContHandPanic( EPushContHandPanUnspecSlHref ) );
       
   879     __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId, 
       
   880                     ContHandPanic( EPushContHandPanAlreadyInitialized ) );
       
   881 
       
   882     CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
       
   883                                           ( *iHrefBuf, KUidWapPushMsgSL );
       
   884     TInt matchingListCount = matchingUrlList->Count();
       
   885     PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
       
   886 
       
   887     // Only one SL is allowed with the same Url, so leave the first and 
       
   888     // delete the others.
       
   889     __ASSERT_DEBUG( matchingListCount <= 1, 
       
   890                     ContHandPanic( EPushContHandPanTooManySl ) );
       
   891     if ( 1 < matchingListCount )
       
   892         {
       
   893         for ( TInt count = 1; count < matchingListCount; ++count )
       
   894             {
       
   895             iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
       
   896             }
       
   897         matchingListCount = 1; // Only one remains.
       
   898         }
       
   899 
       
   900     TBool saveNewMsg = ETrue; // Save by default.
       
   901     TMsvId matchingEntryId = KMsvNullIndexEntryId;
       
   902 
       
   903     // Apply reception rules.
       
   904     if ( matchingListCount == 0 )
       
   905         {
       
   906         // Nothing to do.
       
   907         saveNewMsg = ETrue;
       
   908         }
       
   909     else
       
   910         {
       
   911         CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
       
   912         CleanupStack::PushL( matchingSl );
       
   913 
       
   914         matchingEntryId = matchingUrlList->At(0);
       
   915         matchingSl->RetrieveL( *iMsvSession, matchingEntryId );
       
   916 
       
   917         if ( iPushMsgAction <= matchingSl->Action() ) 
       
   918             {
       
   919             // Discard the new SL: it does not have higher 
       
   920             // action value as the existing.
       
   921             PUSHLOG_WRITE(" SL not higher action - discarded")
       
   922             saveNewMsg = EFalse;
       
   923             }
       
   924         else
       
   925             {
       
   926             // The new has greater action attribute. 
       
   927             // Update the old SL with the new data.
       
   928             saveNewMsg = ETrue;
       
   929             }
       
   930 
       
   931         CleanupStack::PopAndDestroy( matchingSl ); // matchingSl
       
   932         }
       
   933 
       
   934     CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
       
   935 
       
   936     // Store message if not marked for deletion.
       
   937     if ( saveNewMsg )
       
   938         {
       
   939 		StoreSLMessageL( matchingEntryId );
       
   940 		}
       
   941 
       
   942     iState = EDone;
       
   943     IdleComplete();
       
   944 
       
   945     PUSHLOG_LEAVEFN("CSLContentHandler::SavePushMsgEntryL")
       
   946     }
       
   947 
       
   948 // ---------------------------------------------------------
       
   949 // CSLContentHandler::StoreSLMessageL
       
   950 // ---------------------------------------------------------
       
   951 //
       
   952 void CSLContentHandler::StoreSLMessageL( TMsvId aMatchingEntryId )
       
   953 	{
       
   954     PUSHLOG_ENTERFN("CSLContentHandler::StoreSLMessageL")
       
   955 
       
   956 	CSLPushMsgEntry* slEntry = CSLPushMsgEntry::NewL();
       
   957 	CleanupStack::PushL( slEntry );
       
   958 
       
   959     if ( aMatchingEntryId == KMsvNullIndexEntryId )
       
   960         {
       
   961         PUSHLOG_WRITE(" No matching SL")
       
   962         // Save new to Inbox.
       
   963         SetSlPushMsgEntryFieldsL( *slEntry );
       
   964 	    iSavedMsgId = 
       
   965             slEntry->SaveL( *iMsvSession, KMsvGlobalInBoxIndexEntryId );
       
   966         // Set the entry to read and *not* new state depending on iSaveAsRead.
       
   967         if ( !iSaveAsRead )
       
   968             {
       
   969             // Do nothing SaveL saves it as unread.
       
   970             }
       
   971         else
       
   972             {
       
   973             // SaveL owerrides the read settings (iEntry.SetUnread(ETrue);) 
       
   974             // that we set in SetSlPushMsgEntryFieldsL, thus the read status 
       
   975             // has to be reset manually here:
       
   976             iWapPushUtils->MarkServiceUnreadL( iSavedMsgId, EFalse );
       
   977             }
       
   978         }
       
   979     else
       
   980         {
       
   981         PUSHLOG_WRITE(" Matching SL")
       
   982         slEntry->RetrieveL( *iMsvSession, aMatchingEntryId );
       
   983         SetSlPushMsgEntryFieldsL( *slEntry );
       
   984 
       
   985         slEntry->UpdateL( *iMsvSession );
       
   986         iSavedMsgId = aMatchingEntryId;
       
   987         // Note that UpdateL does not change the read/unread status.
       
   988 
       
   989         // Move the updated msg back to Inbox.
       
   990         TMsvId parentId = slEntry->Entry().Parent();
       
   991         if ( parentId != KMsvGlobalInBoxIndexEntryId )
       
   992 	        {
       
   993             PUSHLOG_WRITE(" Moving back to Inbox")
       
   994             CMsvEntry* cParent = iMsvSession->GetEntryL( parentId );
       
   995             CleanupStack::PushL( cParent );
       
   996 	        cParent->MoveL( iSavedMsgId, KMsvGlobalInBoxIndexEntryId );
       
   997             CleanupStack::PopAndDestroy( cParent ); // cParent
       
   998 	        }
       
   999         }
       
  1000 
       
  1001 #ifdef __TEST_LOG__
       
  1002         _LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
       
  1003         _LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
       
  1004         TBuf<32> dateHolder;
       
  1005         TBuf<32> timeHolder;
       
  1006         TTime recDateTime = slEntry->ReceivedDate();
       
  1007         recDateTime.FormatL( dateHolder, KDateFormat );
       
  1008         recDateTime.FormatL( timeHolder, KTimeFormat );
       
  1009         PUSHLOG_WRITE_FORMAT(" rec date: <%S>",&dateHolder)
       
  1010         PUSHLOG_WRITE_FORMAT(" rec time: <%S>",&timeHolder)
       
  1011 #endif // __TEST_LOG__
       
  1012 
       
  1013 	CleanupStack::PopAndDestroy( slEntry ); // slEntry
       
  1014 
       
  1015     PUSHLOG_LEAVEFN("CSLContentHandler::StoreSLMessageL")
       
  1016 	}
       
  1017 
       
  1018 #endif // __SERIES60_PUSH_SL
       
  1019 
       
  1020 // ---------------------------------------------------------
       
  1021 // CSLContentHandler::HandleMessageL
       
  1022 // ---------------------------------------------------------
       
  1023 //
       
  1024 void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg, 
       
  1025                                         TRequestStatus& aStatus )
       
  1026 	{
       
  1027     PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 2")
       
  1028 
       
  1029     __ASSERT_DEBUG( aPushMsg != NULL, 
       
  1030                     ContHandPanic( EPushContHandPanMsgNull ) );
       
  1031 
       
  1032 #ifdef __TEST_LOG__
       
  1033     TPtrC8 bodyPtr;
       
  1034     aPushMsg->GetMessageBody( bodyPtr );
       
  1035     PUSHLOG_HEXDUMP( bodyPtr )
       
  1036 #endif // __TEST_LOG__
       
  1037 
       
  1038 	iMessage = aPushMsg;
       
  1039 	iAcknowledge = ETrue;
       
  1040 	SetConfirmationStatus( aStatus );
       
  1041 
       
  1042 	iState = EGarbageCollecting;
       
  1043 	IdleComplete();
       
  1044 
       
  1045     PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 2")
       
  1046     }
       
  1047 
       
  1048 // ---------------------------------------------------------
       
  1049 // CSLContentHandler::HandleMessageL
       
  1050 // ---------------------------------------------------------
       
  1051 //
       
  1052 void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg )
       
  1053 	{
       
  1054     PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 1")
       
  1055 
       
  1056     __ASSERT_DEBUG( aPushMsg != NULL, 
       
  1057                     ContHandPanic( EPushContHandPanMsgNull ) );
       
  1058 	
       
  1059 #ifdef __TEST_LOG__
       
  1060     TPtrC8 bodyPtr;
       
  1061     aPushMsg->GetMessageBody( bodyPtr );
       
  1062     PUSHLOG_HEXDUMP( bodyPtr )
       
  1063 #endif // __TEST_LOG__
       
  1064 
       
  1065 	iAcknowledge = EFalse;
       
  1066 	iMessage = aPushMsg;
       
  1067 
       
  1068 	iState = EGarbageCollecting;
       
  1069 	IdleComplete();
       
  1070 
       
  1071     PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 1")
       
  1072     }
       
  1073 
       
  1074 // ---------------------------------------------------------
       
  1075 // CSLContentHandler::CancelHandleMessage
       
  1076 // ---------------------------------------------------------
       
  1077 //
       
  1078 void CSLContentHandler::CancelHandleMessage()
       
  1079 	{
       
  1080     Cancel();
       
  1081 	}
       
  1082 
       
  1083 // ---------------------------------------------------------
       
  1084 // CSLContentHandler::CPushHandlerBase_Reserved1
       
  1085 // ---------------------------------------------------------
       
  1086 //
       
  1087 void CSLContentHandler::CPushHandlerBase_Reserved1()
       
  1088 	{
       
  1089 	}
       
  1090 
       
  1091 // ---------------------------------------------------------
       
  1092 // CSLContentHandler::CPushHandlerBase_Reserved1
       
  1093 // ---------------------------------------------------------
       
  1094 //
       
  1095 void CSLContentHandler::CPushHandlerBase_Reserved2()
       
  1096 	{
       
  1097 	}
       
  1098 
       
  1099 // ---------------------------------------------------------
       
  1100 // CSLContentHandler::DoCancel
       
  1101 // ---------------------------------------------------------
       
  1102 //
       
  1103 void CSLContentHandler::DoCancel()
       
  1104 	{
       
  1105     PUSHLOG_ENTERFN("CSLContentHandler::DoCancel")
       
  1106     // TODO Cancel outstanding requests!
       
  1107 	Complete( KErrCancel );
       
  1108     PUSHLOG_LEAVEFN("CSLContentHandler::DoCancel")
       
  1109 	}
       
  1110 
       
  1111 // ---------------------------------------------------------
       
  1112 // CSLContentHandler::RunL
       
  1113 // ---------------------------------------------------------
       
  1114 //
       
  1115 void CSLContentHandler::RunL()
       
  1116 	{
       
  1117     PUSHLOG_ENTERFN("CSLContentHandler::RunL")
       
  1118 
       
  1119     // Handle errors in RunError().
       
  1120     PUSHLOG_WRITE_FORMAT(" iStatus.Int(): %d",iStatus.Int())
       
  1121 
       
  1122 	switch ( iState )
       
  1123 		{
       
  1124 	    case EGarbageCollecting:
       
  1125             {
       
  1126 		    CollectGarbageL();
       
  1127 		    break;
       
  1128             }
       
  1129 
       
  1130 #ifdef __SERIES60_PUSH_SL
       
  1131 
       
  1132         case EFilteringAndParsing:
       
  1133             {
       
  1134             if ( !FilterPushMsgL() )
       
  1135                 {
       
  1136                 // It did not pass the filter. Done.
       
  1137 	            iState = EDone;
       
  1138 	            IdleComplete();
       
  1139                 }
       
  1140             else
       
  1141                 {
       
  1142                 // Continue.
       
  1143 		        TInt ret = KErrNone;
       
  1144 				PUSHLOG_WRITE("CSLContentHandler::RunL : before trapping parsing.")
       
  1145 				TRAP(ret, ParsePushMsgL());
       
  1146 				PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunL : after trapping parsing. ret = %d", ret)
       
  1147 				if ( ret != KErrNone)
       
  1148 					{
       
  1149 					PUSHLOG_WRITE("CSLContentHandler::RunL : Parsing failed. discarding message.")
       
  1150 					iState = EDone;
       
  1151 					IdleComplete();
       
  1152 					}
       
  1153                 }
       
  1154 			break;
       
  1155             }
       
  1156 
       
  1157         case EProcessing:
       
  1158             {
       
  1159 			ProcessingPushMsgEntryL();
       
  1160 			break;
       
  1161             }
       
  1162 
       
  1163 		case EFetching:
       
  1164             {
       
  1165 			FetchPushMsgEntryL();
       
  1166 			break;
       
  1167             }
       
  1168 
       
  1169 		case EFetchCompleted:
       
  1170             {
       
  1171 			FetchCompletedL();
       
  1172 			break;
       
  1173             }
       
  1174 
       
  1175 		case ESavePushMsgEntry:
       
  1176             {
       
  1177 			SavePushMsgEntryL();
       
  1178 			break;
       
  1179             }
       
  1180 
       
  1181 #endif // __SERIES60_PUSH_SL
       
  1182 
       
  1183         case EDone:
       
  1184             {
       
  1185             PUSHLOG_WRITE("CSLContentHandler EDone")
       
  1186 			Complete( KErrNone );
       
  1187 			break;
       
  1188             }
       
  1189 		default:
       
  1190             {
       
  1191             // JIC.
       
  1192             PUSHLOG_WRITE("CSLContentHandler default EDone")
       
  1193 			Complete( KErrNone );
       
  1194 			break;
       
  1195             }
       
  1196 		}
       
  1197 
       
  1198     PUSHLOG_LEAVEFN("CSLContentHandler::RunL")
       
  1199     }
       
  1200 
       
  1201 // ---------------------------------------------------------
       
  1202 // CSLContentHandler::RunError
       
  1203 // ---------------------------------------------------------
       
  1204 //
       
  1205 TInt CSLContentHandler::RunError( TInt aError )
       
  1206 	{
       
  1207     PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunError: %d",aError)
       
  1208 
       
  1209 	iState = EDone;
       
  1210 	Complete( aError );
       
  1211 	return KErrNone;
       
  1212 	}
       
  1213