--- a/pushmtm/Plugins/PushContentHandler/CSLContentHandler.cpp Wed Sep 01 12:31:04 2010 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1221 +0,0 @@
-/*
-* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: Implementation of CSLContentHandler.
-*
-*/
-
-
-
-// INCLUDE FILES
-
-#include "CSLContentHandler.h"
-#include "PushMtmUtil.h"
-#include "PushMtmSettings.h"
-#include "PushAuthenticationUtilities.h"
-#include "PushMtmLog.h"
-#include "PushContentHandlerPanic.h"
-#include "PushMtmAutoFetchOperation.h"
-#include "PushMtmUiDef.h"
-#include "StringResourceReader.h"
-#include "sl_dict.h"
-#include "PushContentHandlerUtils.h"
-#include <push/cslpushmsgentry.h>
-#include <msvids.h>
-#include <apgtask.h>
-#include <apgcli.h>
-#include <w32std.h>
-#include <PushMtmUi.rsg>
-#include <nw_dom_node.h>
-#include <nw_dom_document.h>
-#include <nw_dom_element.h>
-#include <nw_dom_text.h>
-#include <nw_wbxml_dictionary.h>
-#include <nw_string_char.h>
-#include "PushMtmPrivateCRKeys.h"
-#include <centralrepository.h>
-
-// CONSTANTS
-
-// sl attributes / elements
-_LIT8( KSl, "sl" );
-_LIT8( KHref, "href" );
-_LIT8( KAction, "action" );
-
-// action attribute literals
-_LIT8( KExecHigh,"execute-high" );
-_LIT8( KExecLow, "execute-low" );
-_LIT8( KCache, "cache" );
-
-// Text SL MIME type
-_LIT( KSlTextContentType, "text/vnd.wap.sl" );
-
-// Browser command to fetch an URL. See Browser API Specification!
-_LIT( KBrowserCmdFetchUrl, "4 " );
-const TUid KBrowserAppUid = { 0x10008D39 };
-
-const TInt KNoOfDictArrays = 1;
-
-/// Autofetch time delay in seconds.
-const TInt KAutofetchDelayInSec = 5;
-
-// file monitored by browser
-_LIT( KPushMtmUrl, "c:\\system\\temp\\PushMtmUrl.txt" );
-
-// ================= MEMBER FUNCTIONS =======================
-
-// ---------------------------------------------------------
-// CSLContentHandler::NewL
-// ---------------------------------------------------------
-//
-CSLContentHandler* CSLContentHandler::NewL()
- {
- CSLContentHandler* self = new (ELeave) CSLContentHandler;
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
- return self;
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::~CSLContentHandler
-// ---------------------------------------------------------
-//
-CSLContentHandler::~CSLContentHandler()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::~CSLContentHandler")
-
- Cancel();
- delete iFetchOp;
- delete iHrefBuf;
-
- PUSHLOG_LEAVEFN("CSLContentHandler::~CSLContentHandler")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::CSLContentHandler
-// ---------------------------------------------------------
-//
-CSLContentHandler::CSLContentHandler()
-: CPushContentHandlerBase(),
- iSavedMsgId( KMsvNullIndexEntryId ),
- iPushMsgAction( KErrNotFound ),
- iSaveAsRead( EFalse )
- {
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::ConstructL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::ConstructL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::ConstructL")
-
- CRepository* PushSL = CRepository::NewL( KCRUidPushMtm );
- CleanupStack::PushL( PushSL );
- User::LeaveIfError( PushSL->Get( KPushMtmServiceEnabled , iPushSLEnabled ) );
- CleanupStack::PopAndDestroy( PushSL );
-
- CPushContentHandlerBase::ConstructL();
- // Added to Active Scheduler.
- PUSHLOG_LEAVEFN("CSLContentHandler::ConstructL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::CollectGarbageL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::CollectGarbageL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::CollectGarbageL")
-
- DoCollectGarbageL();
-
- if(iPushSLEnabled)
- iState = EFilteringAndParsing;
- else
- iState = EDone;
-
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::CollectGarbageL")
- }
-
-
-// ---------------------------------------------------------
-// CSLContentHandler::ParsePushMsgL
-// Note that cXML parser dosn't do any validation!
-// ---------------------------------------------------------
-//
-void CSLContentHandler::ParsePushMsgL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::ParsePushMsgL")
-
- TPtrC8 bodyPtr;
- iMessage->GetMessageBody( bodyPtr );
- // If there is no body in the message leave with an error
- if ( bodyPtr.Size() == 0 )
- {
- PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: Empty body")
- User::Leave( KErrCorrupt );
- }
-
- TPtrC contentType;
- iMessage->GetContentType( contentType );
- PUSHLOG_WRITE_FORMAT(" Content type <%S>",&contentType)
-
- // Add SL dictionary.
- NW_WBXML_Dictionary_t* dictArray[ KNoOfDictArrays ] =
- { (NW_WBXML_Dictionary_t*)&NW_SL_WBXMLDictionary };
-
- NW_Status_t stat = NW_STAT_SUCCESS;
-
- RWbxmlDictionary wbxmlDict;
- wbxmlDict.InitializeL( KNoOfDictArrays, dictArray );
- CleanupClosePushL<RWbxmlDictionary>( wbxmlDict );
-
- NW_TinyDom_Handle_t domHandle;
- NW_Byte* buffer = (NW_Byte*)bodyPtr.Ptr();
- NW_Int32 length = (NW_Int32)bodyPtr.Size();
- NW_Bool encoded = ( contentType.CompareF( KSlTextContentType ) == 0 ) ?
- NW_FALSE : NW_TRUE;
- NW_Uint32 publicID = NW_SL_PublicId;
- NW_Bool extTNotStringTable = NW_FALSE; // What is this?
- NW_DOM_NodeType_t type = 0;
- /**********************************
- * Root of DOM
- ***********************************/
- CDocumentTreeOwner* docTreeOwner = new (ELeave) CDocumentTreeOwner;
- CleanupStack::PushL( docTreeOwner );
- NW_DOM_DocumentNode_t* domNode = NW_DOM_DocumentNode_BuildTree
- (
- &domHandle,
- buffer,
- length,
- encoded,
- publicID,
- extTNotStringTable
- );
- if (!domNode)
- {
- PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: domNode is Null")
- }
- User::LeaveIfNull( domNode );
- docTreeOwner->SetDocTree( domNode );
-
- type = NW_DOM_Node_getNodeType( domNode );
- if ( type != NW_DOM_DOCUMENT_NODE )
- {
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not Document node <%d>",type)
- User::Leave( KErrArgument );
- }
-
- iCharEncoding = NW_DOM_DocumentNode_getCharacterEncoding( domNode );
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Doc char encoding <%x>",iCharEncoding)
-
- /**********************************
- * ELEMENT sl
- ***********************************/
- // first make sure if there any children in the dom tree, otherwise we will PANIC(in NW_DOM_DocumentNode_getDocumentElement) and crash WatcherMainThread.
- TBool domNodeHasChildNodes = EFalse;
- domNodeHasChildNodes = NW_DOM_Node_hasChildNodes( domNode );
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: check if Dom tree has <SI> node <%d>", domNodeHasChildNodes)
- if (!domNodeHasChildNodes)
- {
- PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: No SL element present in the dom tree. Message corrupted.")
- User::Leave( KErrCorrupt );
- }
-
- PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: before calling getDocumentElement")
- NW_DOM_ElementNode_t* slElement =
- NW_DOM_DocumentNode_getDocumentElement( domNode );
- if (!slElement)
- {
- PUSHLOG_WRITE("CSLContentHandler::ParsePushMsgL: slElement is Null")
- }
- User::LeaveIfNull( slElement );
-
- type = NW_DOM_Node_getNodeType( slElement );
-
- CStringOwner* stringOwner = new (ELeave) CStringOwner;
- CleanupStack::PushL( stringOwner );
-
- NW_String_t* name = NW_String_new();
- User::LeaveIfNull( name );
- stringOwner->SetString( name );
- stat = NW_DOM_Node_getNodeName( slElement, name );
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getNodeName ErrCode: %d", NwxStatusToErrCode( stat ))
- User::LeaveIfError( NwxStatusToErrCode( stat ) );
- NW_Byte* nameBuf = NW_String_getStorage( name );
- NW_Uint16 nameLen = NW_String_getCharCount( name, iCharEncoding );
- TPtrC8 namePtr( nameBuf, nameLen );
-
- if ( type != NW_DOM_ELEMENT_NODE || namePtr.CompareF( KSl ) != 0 )
- {
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: Not sl element node <%d>",type)
- User::Leave( KErrArgument );
- }
-
- CleanupStack::PopAndDestroy( stringOwner ); // stringOwner
-
- /**********************************
- * Attributes of ELEMENT sl
- ***********************************/
- if ( NW_DOM_ElementNode_hasAttributes( slElement ) )
- {
- NW_DOM_AttributeListIterator_t attrIter;
- stat = NW_DOM_ElementNode_getAttributeListIterator
- ( slElement, &attrIter );
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::ParsePushMsgL: getAttribListIter ErrCode: %d", NwxStatusToErrCode( stat ))
- User::LeaveIfError( NwxStatusToErrCode( stat ) );
-
- NW_DOM_AttributeHandle_t attrHandle;
- while( NW_DOM_AttributeListIterator_getNextAttribute
- ( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
- {
- ParseSlAttributeL( attrHandle );
- }
- }
-
- // Cleanup.
- CleanupStack::PopAndDestroy( 2, &wbxmlDict ); // docTreeOwner, wbxmlDict
-
- // if 'action' attribute not specified, the value 'execute-low' is used.
- if ( !ActionFlag() )
- {
- iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteLow;
- SetActionFlag( ETrue );
- PUSHLOG_WRITE_FORMAT(" Defaulting to ActionFlag: %d",iPushMsgAction)
- }
-
- iState = EProcessing;
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::ParsePushMsgL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::ParseSlAttributeL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::ParseSlAttributeL
- ( NW_DOM_AttributeHandle_t& aAttrHandle )
- {
- PUSHLOG_ENTERFN("CSLContentHandler::ParseSlAttributeL")
-
- NW_Status_t stat = NW_STAT_SUCCESS;
-
- CStringOwner* attrNameOwner = new (ELeave) CStringOwner;
- CleanupStack::PushL( attrNameOwner );
-
- NW_String_t* attrName = NW_String_new();
- User::LeaveIfNull( attrName );
- attrNameOwner->SetString( attrName );
-
- // Get the name of the attribute.
- stat = NW_DOM_AttributeHandle_getName( &aAttrHandle, attrName );
- User::LeaveIfError( NwxStatusToErrCode( stat ) );
- NW_Byte* attrNameBuf = NW_String_getStorage( attrName );
- NW_Uint16 attrNameLen = NW_String_getCharCount( attrName, iCharEncoding );
- TPtrC8 attrNamePtr( attrNameBuf, attrNameLen );
-
- if ( attrNamePtr.CompareF( KHref ) == 0 )
- {
- if ( !HrefFlag() )
- {
- HBufC* tempHrefBuf = NULL;
-
- CStringOwner* valOwner = new (ELeave) CStringOwner;
- CleanupStack::PushL( valOwner );
-
- NW_String_t* val = NW_String_new();
- User::LeaveIfNull( val );
- valOwner->SetString( val );
- stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
- if ( stat != NW_STAT_DOM_NO_STRING_RETURNED )
- {
- User::LeaveIfError( NwxStatusToErrCode( stat ) );
- NW_Byte* storage = NW_String_getStorage( val );
- NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
- TPtrC8 prefixPtr( storage, length );
- tempHrefBuf = HBufC::NewMaxL( length );
- // No leavable after it!!! until...
- tempHrefBuf->Des().Copy( prefixPtr );
- }
-
- CleanupStack::PopAndDestroy( valOwner ); // valOwner
-
- if ( tempHrefBuf )
- {
- if ( tempHrefBuf->Length() == 0 )
- {
- // Zero length Href is considered as nothing.
- PUSHLOG_WRITE(" Zero length HrefFlag");
- }
- else
- {
- iHrefBuf = tempHrefBuf; // ...until here.
- SetHrefFlag( ETrue );
- PUSHLOG_WRITE_FORMAT(" HrefFlag set <%S>",iHrefBuf);
- }
- }
- }
- }
- else if ( attrNamePtr.CompareF( KAction ) == 0 )
- {
- if ( !ActionFlag() )
- {
- CStringOwner* stringOwner = new (ELeave) CStringOwner;
- CleanupStack::PushL( stringOwner );
-
- NW_String_t* val = NW_String_new();
- User::LeaveIfNull( val );
- stringOwner->SetString( val );
- stat = NW_DOM_AttributeHandle_getValue( &aAttrHandle, val );
- User::LeaveIfError( NwxStatusToErrCode( stat ) );
- NW_Byte* storage = NW_String_getStorage( val );
- NW_Uint16 length = NW_String_getCharCount( val, iCharEncoding );
- TPtrC8 actionPtr( storage, length );
-
- iPushMsgAction = ConvertActionString( actionPtr );
- SetActionFlag( ETrue );
- PUSHLOG_WRITE_FORMAT(" ActionFlag: %d",iPushMsgAction)
-
- CleanupStack::PopAndDestroy( stringOwner );
- }
- }
- else
- {
- __ASSERT_DEBUG( EFalse,
- ContHandPanic( EPushContHandPanUnexpSlToken ) );
- }
-
- CleanupStack::PopAndDestroy( attrNameOwner ); // attrNameOwner
-
- PUSHLOG_LEAVEFN("CSLContentHandler::ParseSlAttributeL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::ConvertActionString
-// ---------------------------------------------------------
-//
-TUint CSLContentHandler::ConvertActionString
- ( const TDesC8& aActionString ) const
- {
- const TInt KMatchFound = 0;
-
- // if 'action' attribute not specified, the value 'execute-low' is used.
- TUint actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
-
- if ( aActionString.Compare( KExecHigh ) == KMatchFound )
- {
- actionValue = CSLPushMsgEntry::ESLPushMsgExecuteHigh;
- }
- else if ( aActionString.Compare( KExecLow ) == KMatchFound )
- {
- actionValue = CSLPushMsgEntry::ESLPushMsgExecuteLow;
- }
- else if ( aActionString.Compare( KCache ) == KMatchFound )
- {
- actionValue = CSLPushMsgEntry::ESLPushMsgExecuteCache;
- }
-
- return actionValue;
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::SetSlPushMsgEntryFieldsL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::SetSlPushMsgEntryFieldsL( CSLPushMsgEntry&
- aSlPushMsgEntry ) const
- {
- PUSHLOG_ENTERFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
-
- // Set URL and Action fields.
- if ( HrefFlag() )
- {
- aSlPushMsgEntry.SetUrlL( *iHrefBuf );
- }
-
- __ASSERT_DEBUG( ActionFlag(),
- ContHandPanic( EPushContHandPanUnspecSlAction ) );
- if ( ActionFlag() )
- {
- aSlPushMsgEntry.SetAction( iPushMsgAction );
- }
- else // if not specified, the value 'execute-low' is used.
- {
- aSlPushMsgEntry.SetAction( CSLPushMsgEntry::ESLPushMsgExecuteLow );
- }
-
- // Set all the relevant header fields.
- TPtrC8 msgHeaderPtr;
- iMessage->GetHeader( msgHeaderPtr );
- aSlPushMsgEntry.SetHeaderL( msgHeaderPtr );
-
- // Get server address.
- TPtrC8 srvAddress;
- if ( iMessage->GetServerAddress( srvAddress ) )
- {
- aSlPushMsgEntry.SetFromL( srvAddress );
- }
-
- // First line in Inbox: TMsvEntry::iDetails.
- if ( srvAddress.Length() == 0 )
- {
- // Read from resource.
- HBufC* details =
- iStrRscReader->AllocReadResourceLC( R_PUSHMISC_UNK_SENDER );
- aSlPushMsgEntry.SetMsgDetailsL( *details );
- CleanupStack::PopAndDestroy( details );
- }
- else
- {
- // Convert the "From" information to the format required by the UI
- // spec and then decode it.
- HBufC* details = iWapPushUtils->ConvertDetailsL( srvAddress );
- CleanupStack::PushL( details );
- HBufC* convertedFrom =
- CPushMtmUtil::ConvertUriToDisplayFormL( *details );
- CleanupStack::PushL( convertedFrom );
- //
- aSlPushMsgEntry.SetMsgDetailsL( *convertedFrom );
- //
- CleanupStack::PopAndDestroy( 2, details ); // convertedFrom, details
- }
-
- // Second line in Inbox: TMsvEntry::iDescription.
- // Read from resource.
- HBufC* description =
- iStrRscReader->AllocReadResourceLC( R_PUSHMISC_INBOX_SERV_MSG );
- aSlPushMsgEntry.SetMsgDescriptionL( *description );
- CleanupStack::PopAndDestroy( description );
-
- // ******** Push MTM specific processing *********
-
- /*
- * Unfortunately in CPushMsgEntryBase there is no such functionality
- * with which we can reach TMsvEntry as non-const, but we have to
- * modify the entry's iMtmData2 member somehow. We can do it
- * with either casting or with modifying and saving the entry
- * manually after it has been saved by CSLPushMsgEntry. The latter
- * solution is more expensive so we choose the first.
- */
- TMsvEntry& tEntry = CONST_CAST( TMsvEntry&, aSlPushMsgEntry.Entry() );
- if ( HrefFlag() )
- {
- CPushMtmUtil::SetAttrs( tEntry, EPushMtmAttrHasHref );
- }
- else
- {
- CPushMtmUtil::ResetAttrs( tEntry, EPushMtmAttrHasHref );
- }
-
- // Indication is required if the entry is saved as 'read' (delete &
- // replacement notification). It can happen only in case of SL message.
- // Otherwise the flag has to be cleared!
- if ( !iSaveAsRead )
- {
- // Saving as unread & new.
- tEntry.SetNew( ETrue );
- tEntry.SetUnread( ETrue );
- CPushMtmUtil::ResetAttrs( tEntry, EPushMtmReadButContentChanged );
- }
- else
- {
- // Saving as read.
- tEntry.SetNew( EFalse );
- tEntry.SetUnread( EFalse );
- CPushMtmUtil::SetAttrs( tEntry, EPushMtmReadButContentChanged );
- }
-
- PUSHLOG_LEAVEFN("CSLContentHandler::SetSlPushMsgEntryFieldsL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::ProcessingPushMsgEntryL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::ProcessingPushMsgEntryL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::ProcessingPushMsgEntryL")
-
- TBool discardPushMsg( EFalse );
-
- __ASSERT_DEBUG( ActionFlag(),
- ContHandPanic( EPushContHandPanUnspecSlAction ) );
-
- // S60 requirement: if the href is empty then delete (discard) the msg.
- if ( HrefFlag() == EFalse )
- {
- PUSHLOG_WRITE(" No SL Href.")
- discardPushMsg = ETrue;
- }
- else
- {
- __ASSERT_DEBUG( HrefFlag() && iHrefBuf,
- ContHandPanic( EPushContHandPanUnspecSlHref ) );
-
- // The message will not be discarded
- discardPushMsg = EFalse;
-
- CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
- ( *iHrefBuf, KUidWapPushMsgSL );
- TInt matchingListCount = matchingUrlList->Count();
- PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
-
- // Only one SL is allowed with the same Url, so leave the first and
- // delete the others.
- if ( 1 < matchingListCount )
- {
- for ( TInt count = 1; count < matchingListCount; ++count )
- {
- iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
- }
- matchingListCount = 1; // Only one remains.
- }
-
- if ( 0 < matchingListCount )
- {
- // Find msg of the same href and discard it if it has a lower or
- // the same action value.
- CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
- CleanupStack::PushL( matchingSl );
-
- const TMsvId matchingId = matchingUrlList->At(0);
- matchingSl->RetrieveL( *iMsvSession, matchingId );
-
- if ( iPushMsgAction <= matchingSl->Action() )
- {
- PUSHLOG_WRITE(" SL: not higher action")
- discardPushMsg = ETrue;
- }
-
- CleanupStack::PopAndDestroy( matchingSl ); // matchingSl,
- }
-
- CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
- }
-
- if ( discardPushMsg )
- {
- // Nothing to do.
- PUSHLOG_WRITE(" SL discarded.")
- iState = EDone;
- IdleComplete();
- }
- else
- {
- iState = HandleServiceInvocationL();
- IdleComplete();
- }
-
- __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId,
- ContHandPanic( EPushContHandPanSlMsgIdSet ) );
-
- PUSHLOG_LEAVEFN("CSLContentHandler::ProcessingPushMsgEntryL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::HandleServiceInvocationL
-// ---------------------------------------------------------
-//
-TInt CSLContentHandler::HandleServiceInvocationL() const
- {
- PUSHLOG_ENTERFN("CSLContentHandler::HandleServiceInvocationL")
-
- TInt nextState = ESavePushMsgEntry;
-
- if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
- {
- PUSHLOG_WRITE(" SL cache");
- TBool isAuthenticated = TPushAuthenticationUtil::
- AuthenticateMsgL( *iMtmSettings, *iMessage );
- if ( !isAuthenticated )
- {
- PUSHLOG_WRITE(" Not authenticated");
- // The message is placed to Inbox.
- nextState = ESavePushMsgEntry;
- }
- else
- {
- // Authenticated. Fetch SL-cache.
- nextState = EFetching;
- }
- }
-
- else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteLow )
- {
- PUSHLOG_WRITE(" SL execute-low")
- // It is independent from Automatic/Manual setting and WL
- // authentication is not applied. The message is placed to Inbox
- // for manual downloading.
- nextState = ESavePushMsgEntry;
- }
-
- else // ESLPushMsgExecuteHigh
- {
- PUSHLOG_WRITE(" SL execute-high");
- // If the settings is Manual or it does not pass the WL authentication
- // then it is placed to Inbox for manual downloading.
- // If the setting is Automatic and it passes the WL authentication,
- // the Browser is started standalone to download the URL without any
- // user interaction.
- if ( iMtmSettings->ServiceLoadingType() ==
- CPushMtmSettings::EManual )
- {
- PUSHLOG_WRITE(" Manual setting")
- // The message is placed to Inbox.
- nextState = ESavePushMsgEntry;
- }
- else // Automatic loading
- {
- PUSHLOG_WRITE(" Automatic setting");
- // Authenticate the message.
- TBool isAuthenticated = TPushAuthenticationUtil::
- AuthenticateMsgL( *iMtmSettings, *iMessage );
- if ( !isAuthenticated )
- {
- PUSHLOG_WRITE(" Not authenticated");
- // The message is placed to Inbox.
- nextState = ESavePushMsgEntry;
- }
- else
- {
- // Authenticated - start downloading.
- nextState = EFetching;
- }
- }
- }
-
- PUSHLOG_LEAVEFN("CSLContentHandler::HandleServiceInvocationL")
- return nextState;
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::FetchPushMsgEntryL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::FetchPushMsgEntryL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::FetchPushMsgEntryL")
-
- __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId,
- ContHandPanic( EPushContHandPanAlreadyInitialized ) );
- __ASSERT_DEBUG( HrefFlag() && iHrefBuf,
- ContHandPanic( EPushContHandPanUnspecSlHref ) );
-
- /*
- * In case of execute-high use the Browser to download the service.
- * In case of cache use the fetch operation to download the service
- * silently.
- */
-
- if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteHigh )
- {
- PUSHLOG_WRITE(" Start Browser")
- // Launch the Browser with the URI, then save the message.
- // Trap errors. If Browser's launching fails, then save the
- // message as 'unread'. In case of an error, it is not forwarded.
- TRAPD( err, StartBrowserL() );
- iState = ESavePushMsgEntry;
- // Mark it 'read' after succesfull Browser startup.
- iSaveAsRead = err ? EFalse : ETrue;
- IdleComplete();
- }
- else if ( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache )
- {
- // Fetch the service inside the content handler.
- iStatus = KRequestPending;
- SetActive();
- __ASSERT_DEBUG( !iFetchOp,
- ContHandPanic( EPushContHandPanFetchAlreadyInit ) );
-
- iFetchOp = CPushMtmAutoFetchOperation::NewL( *iHrefBuf,
- KAutofetchDelayInSec,
- iStatus );
- iFetchOp->StartL();
- PUSHLOG_WRITE(" Fetch op started")
- iState = EFetchCompleted; // Next state.
- // Fetch completes it.
- }
- else
- {
- __ASSERT_DEBUG( EFalse,
- ContHandPanic( EPushContHandPanBadActionValue ) );
- User::Leave( KErrNotSupported );
- }
-
- PUSHLOG_LEAVEFN("CSLContentHandler::FetchPushMsgEntryL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::StartBrowserL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::StartBrowserL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::StartBrowserL")
-
- // Parameters are separated by space
- // 1st parameter: type of the further parameters
- // 2nd parameter: URL
- //
- HBufC* param = HBufC::NewLC( KBrowserCmdFetchUrl().Length() +
- iHrefBuf->Length() );
- TPtr paramPtr = param->Des();
- paramPtr.Copy( KBrowserCmdFetchUrl );
- paramPtr.Append( *iHrefBuf );
-
- RWsSession wsSession;
- User::LeaveIfError( wsSession.Connect() );
- CleanupClosePushL<RWsSession>( wsSession );
- TApaTaskList taskList( wsSession );
- TApaTask task = taskList.FindApp( KBrowserAppUid );
-
- if ( task.Exists() )
- {
- PUSHLOG_WRITE("CSLContentHandler Browser::SendMessage")
-
- RFs rfs;
- RFile file;
- TPtrC8 param8Ptr;
- // 8-bit buffer is required.
- HBufC8* param8 = HBufC8::NewLC( param->Length() );
- param8->Des().Copy( *param );
- param8Ptr.Set(param8->Des());
-
- // Open the file.
- User::LeaveIfError(rfs.Connect());
- CleanupClosePushL(rfs);
-
- // Replace file if exists or Create file if not exist yet
- User::LeaveIfError( file.Replace( rfs, KPushMtmUrl, EFileWrite | EFileShareExclusive ) );
- CleanupClosePushL(file);
-
- // Write to file
- User::LeaveIfError( file.Write( param8Ptr ) );
-
- // Clean up.
- CleanupStack::PopAndDestroy(/*file*/);
- CleanupStack::PopAndDestroy(/*rfs*/);
- CleanupStack::PopAndDestroy( /*param8*/ );
- }
- else
- {
- PUSHLOG_WRITE("CSLContentHandler Browser::StartDocument")
- RApaLsSession appArcSession;
- User::LeaveIfError( appArcSession.Connect() );
- CleanupClosePushL<RApaLsSession>( appArcSession );
- TThreadId id;
- User::LeaveIfError
- (
- appArcSession.StartDocument( *param, KBrowserAppUid, id )
- );
- CleanupStack::PopAndDestroy( &appArcSession );
- }
-
- CleanupStack::PopAndDestroy( &wsSession );
- CleanupStack::PopAndDestroy( param );
-
- PUSHLOG_LEAVEFN("CSLContentHandler::StartBrowserL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::FetchCompletedL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::FetchCompletedL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::FetchCompletedL")
-
- __ASSERT_DEBUG( iPushMsgAction == CSLPushMsgEntry::ESLPushMsgExecuteCache,
- ContHandPanic( EPushContHandPanBadActionValue ) );
- __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId,
- ContHandPanic( EPushContHandPanAlreadyInitialized ) );
- __ASSERT_DEBUG( iFetchOp, ContHandPanic( EPushContHandPanNoFetchOp ) );
-
- const TInt fetchRes = iStatus.Int();
- PUSHLOG_WRITE_FORMAT(" fetchRes <%d>",fetchRes)
-
- if ( fetchRes != KErrNone )
- {
- // Downloading failed. Save the message.
- iState = ESavePushMsgEntry;
- }
- else
- {
- // Silent fetching has completed successfully.
- // The message should not be saved.
- iState = EDone;
- }
-
- // Next state set. Complete.
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::FetchCompletedL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::SavePushMsgEntryL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::SavePushMsgEntryL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::SavePushMsgEntryL")
-
- __ASSERT_DEBUG( ActionFlag(),
- ContHandPanic( EPushContHandPanUnspecSlAction ) );
- __ASSERT_DEBUG( HrefFlag() && iHrefBuf,
- ContHandPanic( EPushContHandPanUnspecSlHref ) );
- __ASSERT_DEBUG( iSavedMsgId == KMsvNullIndexEntryId,
- ContHandPanic( EPushContHandPanAlreadyInitialized ) );
-
- CMsvEntrySelection* matchingUrlList = iWapPushUtils->FindUrlLC
- ( *iHrefBuf, KUidWapPushMsgSL );
- TInt matchingListCount = matchingUrlList->Count();
- PUSHLOG_WRITE_FORMAT(" matchingListCount: %d",matchingListCount)
-
- // Only one SL is allowed with the same Url, so leave the first and
- // delete the others.
- __ASSERT_DEBUG( matchingListCount <= 1,
- ContHandPanic( EPushContHandPanTooManySl ) );
- if ( 1 < matchingListCount )
- {
- for ( TInt count = 1; count < matchingListCount; ++count )
- {
- iWapPushUtils->DeleteEntryL( matchingUrlList->At(count) );
- }
- matchingListCount = 1; // Only one remains.
- }
-
- TBool saveNewMsg = ETrue; // Save by default.
- TMsvId matchingEntryId = KMsvNullIndexEntryId;
-
- // Apply reception rules.
- if ( matchingListCount == 0 )
- {
- // Nothing to do.
- saveNewMsg = ETrue;
- }
- else
- {
- CSLPushMsgEntry* matchingSl = CSLPushMsgEntry::NewL();
- CleanupStack::PushL( matchingSl );
-
- matchingEntryId = matchingUrlList->At(0);
- matchingSl->RetrieveL( *iMsvSession, matchingEntryId );
-
- if ( iPushMsgAction <= matchingSl->Action() )
- {
- // Discard the new SL: it does not have higher
- // action value as the existing.
- PUSHLOG_WRITE(" SL not higher action - discarded")
- saveNewMsg = EFalse;
- }
- else
- {
- // The new has greater action attribute.
- // Update the old SL with the new data.
- saveNewMsg = ETrue;
- }
-
- CleanupStack::PopAndDestroy( matchingSl ); // matchingSl
- }
-
- CleanupStack::PopAndDestroy( matchingUrlList ); // matchingUrlList
-
- // Store message if not marked for deletion.
- if ( saveNewMsg )
- {
- StoreSLMessageL( matchingEntryId );
- }
-
- iState = EDone;
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::SavePushMsgEntryL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::StoreSLMessageL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::StoreSLMessageL( TMsvId aMatchingEntryId )
- {
- PUSHLOG_ENTERFN("CSLContentHandler::StoreSLMessageL")
-
- CSLPushMsgEntry* slEntry = CSLPushMsgEntry::NewL();
- CleanupStack::PushL( slEntry );
-
- if ( aMatchingEntryId == KMsvNullIndexEntryId )
- {
- PUSHLOG_WRITE(" No matching SL")
- // Save new to Inbox.
- SetSlPushMsgEntryFieldsL( *slEntry );
- iSavedMsgId =
- slEntry->SaveL( *iMsvSession, KMsvGlobalInBoxIndexEntryId );
- // Set the entry to read and *not* new state depending on iSaveAsRead.
- if ( !iSaveAsRead )
- {
- // Do nothing SaveL saves it as unread.
- }
- else
- {
- // SaveL owerrides the read settings (iEntry.SetUnread(ETrue);)
- // that we set in SetSlPushMsgEntryFieldsL, thus the read status
- // has to be reset manually here:
- iWapPushUtils->MarkServiceUnreadL( iSavedMsgId, EFalse );
- }
- }
- else
- {
- PUSHLOG_WRITE(" Matching SL")
- slEntry->RetrieveL( *iMsvSession, aMatchingEntryId );
- SetSlPushMsgEntryFieldsL( *slEntry );
-
- slEntry->UpdateL( *iMsvSession );
- iSavedMsgId = aMatchingEntryId;
- // Note that UpdateL does not change the read/unread status.
-
- // Move the updated msg back to Inbox.
- TMsvId parentId = slEntry->Entry().Parent();
- if ( parentId != KMsvGlobalInBoxIndexEntryId )
- {
- PUSHLOG_WRITE(" Moving back to Inbox")
- CMsvEntry* cParent = iMsvSession->GetEntryL( parentId );
- CleanupStack::PushL( cParent );
- cParent->MoveL( iSavedMsgId, KMsvGlobalInBoxIndexEntryId );
- CleanupStack::PopAndDestroy( cParent ); // cParent
- }
- }
-
-#ifdef __TEST_LOG__
- _LIT( KDateFormat, "%E%D%X%N%Y %1 %2 %3" );
- _LIT( KTimeFormat, "%-B%:0%J%:1%T%:2%S%:3%+B" );
- TBuf<32> dateHolder;
- TBuf<32> timeHolder;
- TTime recDateTime = slEntry->ReceivedDate();
- recDateTime.FormatL( dateHolder, KDateFormat );
- recDateTime.FormatL( timeHolder, KTimeFormat );
- PUSHLOG_WRITE_FORMAT(" rec date: <%S>",&dateHolder)
- PUSHLOG_WRITE_FORMAT(" rec time: <%S>",&timeHolder)
-#endif // __TEST_LOG__
-
- CleanupStack::PopAndDestroy( slEntry ); // slEntry
-
- PUSHLOG_LEAVEFN("CSLContentHandler::StoreSLMessageL")
- }
-
-
-// ---------------------------------------------------------
-// CSLContentHandler::HandleMessageL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg,
- TRequestStatus& aStatus )
- {
- PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 2")
-
- __ASSERT_DEBUG( aPushMsg != NULL,
- ContHandPanic( EPushContHandPanMsgNull ) );
-
-#ifdef __TEST_LOG__
- TPtrC8 bodyPtr;
- aPushMsg->GetMessageBody( bodyPtr );
- PUSHLOG_HEXDUMP( bodyPtr )
-#endif // __TEST_LOG__
-
- iMessage = aPushMsg;
- iAcknowledge = ETrue;
- SetConfirmationStatus( aStatus );
-
- iState = EGarbageCollecting;
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 2")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::HandleMessageL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::HandleMessageL( CPushMessage* aPushMsg )
- {
- PUSHLOG_ENTERFN("CSLContentHandler::HandleMessageL 1")
-
- __ASSERT_DEBUG( aPushMsg != NULL,
- ContHandPanic( EPushContHandPanMsgNull ) );
-
-#ifdef __TEST_LOG__
- TPtrC8 bodyPtr;
- aPushMsg->GetMessageBody( bodyPtr );
- PUSHLOG_HEXDUMP( bodyPtr )
-#endif // __TEST_LOG__
-
- iAcknowledge = EFalse;
- iMessage = aPushMsg;
-
- iState = EGarbageCollecting;
- IdleComplete();
-
- PUSHLOG_LEAVEFN("CSLContentHandler::HandleMessageL 1")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::CancelHandleMessage
-// ---------------------------------------------------------
-//
-void CSLContentHandler::CancelHandleMessage()
- {
- Cancel();
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::CPushHandlerBase_Reserved1
-// ---------------------------------------------------------
-//
-void CSLContentHandler::CPushHandlerBase_Reserved1()
- {
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::CPushHandlerBase_Reserved1
-// ---------------------------------------------------------
-//
-void CSLContentHandler::CPushHandlerBase_Reserved2()
- {
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::DoCancel
-// ---------------------------------------------------------
-//
-void CSLContentHandler::DoCancel()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::DoCancel")
- // TODO Cancel outstanding requests!
- Complete( KErrCancel );
- PUSHLOG_LEAVEFN("CSLContentHandler::DoCancel")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::RunL
-// ---------------------------------------------------------
-//
-void CSLContentHandler::RunL()
- {
- PUSHLOG_ENTERFN("CSLContentHandler::RunL")
-
- // Handle errors in RunError().
- PUSHLOG_WRITE_FORMAT(" iStatus.Int(): %d",iStatus.Int())
-
- switch ( iState )
- {
- case EGarbageCollecting:
- {
- CollectGarbageL();
- break;
- }
-
-
- case EFilteringAndParsing:
- {
- if(iPushSLEnabled)
- {
- if ( !FilterPushMsgL() )
- {
- // It did not pass the filter. Done.
- iState = EDone;
- IdleComplete();
- }
- else
- {
- // Continue.
- TInt ret = KErrNone;
- PUSHLOG_WRITE("CSLContentHandler::RunL : before trapping parsing.")
- TRAP(ret, ParsePushMsgL());
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunL : after trapping parsing. ret = %d", ret)
- if ( ret != KErrNone)
- {
- PUSHLOG_WRITE("CSLContentHandler::RunL : Parsing failed. discarding message.")
- iState = EDone;
- IdleComplete();
- }
- }
- }
- break;
- }
-
- case EProcessing:
- {
- if(iPushSLEnabled)
- ProcessingPushMsgEntryL();
- break;
- }
-
- case EFetching:
- {
- if(iPushSLEnabled)
- FetchPushMsgEntryL();
- break;
- }
-
- case EFetchCompleted:
- {
- if(iPushSLEnabled)
- FetchCompletedL();
- break;
- }
-
- case ESavePushMsgEntry:
- {
- if(iPushSLEnabled)
- SavePushMsgEntryL();
- break;
- }
-
-
- case EDone:
- {
- PUSHLOG_WRITE("CSLContentHandler EDone")
- Complete( KErrNone );
- break;
- }
- default:
- {
- // JIC.
- PUSHLOG_WRITE("CSLContentHandler default EDone")
- Complete( KErrNone );
- break;
- }
- }
-
- PUSHLOG_LEAVEFN("CSLContentHandler::RunL")
- }
-
-// ---------------------------------------------------------
-// CSLContentHandler::RunError
-// ---------------------------------------------------------
-//
-TInt CSLContentHandler::RunError( TInt aError )
- {
- PUSHLOG_WRITE_FORMAT("CSLContentHandler::RunError: %d",aError)
-
- iState = EDone;
- Complete( aError );
- return KErrNone;
- }
-