--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/idlefw/plugins/wrtdataplugin/src/wrtdataplugin.cpp Wed Sep 01 12:22:09 2010 +0100
@@ -0,0 +1,910 @@
+/*
+* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: WRT data plug-in publisher
+*
+*/
+
+// System includes
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include <PUAcodes.hrh>
+#include <badesca.h>
+#include <fbs.h>
+#include <gulicon.h>
+#include <AknsSkinInstance.h>
+#include <AknsUtils.h>
+#include <AknsConstants.h>
+#include <e32property.h>
+
+// User includes
+#include <hspublisherinfo.h>
+#include <aicontentobserver.h>
+#include <aiutility.h>
+#include <aipspropertyobserver.h>
+#include <aipluginsettings.h>
+#include <activeidle2domainpskeys.h>
+#include <debug.h>
+
+#include "wrtdatapluginconst.h"
+#include "wrtdatapluginuids.hrh"
+#include "wrtdataplugin.h"
+#include "wrtdata.h"
+
+// Constants
+const TImplementationProxy KImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY( KImplUidDataPlugin, CWrtDataPlugin::NewL )
+ };
+
+const TInt KTryAgainDelay( 3000000 ); // 3 sec
+
+// ======== MEMBER FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// ImplementationGroupProxy
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(
+ TInt& aTableCount )
+ {
+ aTableCount = sizeof( KImplementationTable ) /
+ sizeof( TImplementationProxy );
+ return KImplementationTable;
+ }
+
+// ======== MEMBER FUNCTIONS ========
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::NewL()
+//
+// ----------------------------------------------------------------------------
+//
+CWrtDataPlugin* CWrtDataPlugin::NewL()
+ {
+ CWrtDataPlugin* self = new (ELeave) CWrtDataPlugin;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::CWrtDataPlugin()
+//
+// ----------------------------------------------------------------------------
+//
+CWrtDataPlugin::CWrtDataPlugin()
+ : iNetworkStatus( EUnknown ), iPluginState( EStopped )
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::ConstructL()
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::ConstructL()
+ {
+ User::LeaveIfError( iRfs.Connect() );
+
+ iData = CWrtData::NewL( this );
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// Deletes all data created to heap
+// ---------------------------------------------------------------------------
+//
+CWrtDataPlugin::~CWrtDataPlugin()
+ {
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ delete iTimer;
+ }
+
+ delete iData;
+ iObservers.Close();
+ Release( iContent );
+ iDataArray.ResetAndDestroy();
+
+ if( iContentModel)
+ {
+ for( TInt i = iDataCount-1;i>=0 ; i-- )
+ {
+ User::Free((TAny*)iContentModel[i].cid);
+ }
+ delete []iContentModel;
+ }
+ iIconArray.Reset();
+
+ iRfs.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::Start
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::Start( TStartReason aReason )
+ {
+ iPluginState = EStarted;
+
+ if( aReason == ESystemStartup ||
+ aReason == EPluginStartup )
+ {
+ // Publish the initial data
+ TRAP_IGNORE( PublishInitialDataL() );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::Stop
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::Stop( TStopReason aReason )
+ {
+ iPluginState = EStopped;
+
+ if( aReason == EPluginShutdown ||
+ aReason == ESystemShutdown )
+ {
+ TRAP_IGNORE(iData->NotifyPublisherL( KDeActive ));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::Resume
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::Resume( TResumeReason aReason )
+ {
+ if ( aReason == EForeground && iPluginState != EStopped )
+ {
+ iPluginState = EResume;
+
+ TRAP_IGNORE( iData->NotifyPublisherL( KResume ));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::Suspend
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::Suspend( TSuspendReason aReason )
+ {
+ if ( aReason == EBackground && iPluginState != EStopped )
+ {
+ iPluginState = ESuspend;
+
+ TRAP_IGNORE ( iData->NotifyPublisherL( KSuspend ));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::SetOnline
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::SetOnline()
+ {
+ if ( iPluginState != EStopped )
+ {
+ iNetworkStatus = EOnline;
+ TRAP_IGNORE( iData->NotifyPublisherL( KOnLine ));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::SetOffline
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::SetOffline()
+ {
+ if ( iPluginState != EStopped )
+ {
+ iNetworkStatus = EOffline;
+ TRAP_IGNORE( iData->NotifyPublisherL( KOffLine ));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::SubscribeL
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::SubscribeL( MAiContentObserver& aObserver )
+ {
+ iObservers.AppendL( &aObserver );
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::ConfigureL
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::ConfigureL( RAiSettingsItemArray& aSettings )
+ {
+ RAiSettingsItemArray contentItemsArr;
+ RAiSettingsItemArray configurationItemsArr;
+ TInt count( aSettings.Count() );
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ MAiPluginSettings* setting( aSettings[i] );
+
+ if( setting->AiPluginItemType() == EAiPluginContentItem )
+ {
+ contentItemsArr.Append( setting );
+ }
+ else if( setting->AiPluginItemType() == EAiPluginConfigurationItem )
+ {
+ configurationItemsArr.Append( setting );
+ }
+ }
+
+ iDataCount = contentItemsArr.Count();
+
+ // Create the content Model
+ HBufC16* contentId = HBufC16::NewLC(
+ KAiContentIdMaxLength + KAiPluginNameMaxLength );
+
+ iContentModel = new TAiContentItem[iDataCount];
+
+ for( TInt i = 0; i < iDataCount; i++ )
+ {
+ MAiPluginContentItem& contentItem(
+ contentItemsArr[i]->AiPluginContentItem() );
+
+ iContentModel[i].id = i;
+ if( contentItem.Type() == KText() )
+ {
+ // text
+ iContentModel[i].type = KAiContentTypeText;
+ }
+ if( contentItem.Type() == KImage() ||
+ contentItem.Type() == KAnimation() )
+ {
+ // image
+ iContentModel[i].type = KAiContentTypeBitmap;
+ }
+
+ contentId->Des().Copy( contentItem.Name() );
+ contentId->Des().Delete( 0,
+ contentId->Des().LocateReverse( KPluginNameSeprator ) + 1 );
+
+ TInt sizeOfContentId( contentId->Des().Size()+sizeof( wchar_t ) );
+
+ iContentModel[i].cid =
+ static_cast< const wchar_t* >( User::Alloc( sizeOfContentId ) );
+
+ Mem::Copy( ( TAny* )iContentModel[i].cid,
+ contentId->Des().PtrZ(), sizeOfContentId );
+
+ contentId->Des().Delete( 0, contentId->Des().Length() );
+ }
+
+ CleanupStack::PopAndDestroy( contentId );
+ iContent = AiUtility::CreateContentItemArrayIteratorL(
+ iContentModel, iDataCount );
+
+ // Configurations
+ iData->ConfigureL( configurationItemsArr );
+
+ // Register for notifications
+ iData->RegisterL();
+
+ // Activate the publisher
+ iData->NotifyPublisherL( KActive );
+
+ contentItemsArr.Reset();
+ configurationItemsArr.Reset();
+ // We own the array so destroy it
+ aSettings.ResetAndDestroy();
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::SetProperty
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::SetProperty( TProperty aProperty, TAny* aAny )
+ {
+ if (aProperty == ECpsCmdBuffer )
+ {
+ iData->SetCommandBuffer( aAny, PublisherInfo().Namespace() );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::GetProperty
+//
+// ----------------------------------------------------------------------------
+//
+TAny* CWrtDataPlugin::GetProperty( TProperty aProperty )
+ {
+ if ( aProperty == EPublisherContent )
+ {
+ return static_cast< MAiContentItemIterator* >( iContent );
+ }
+
+ return NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::HandleEvent
+//
+// ----------------------------------------------------------------------------
+//
+void CWrtDataPlugin::HandleEvent( const TDesC& aEventName,
+ const TDesC& aParam )
+ {
+ TRAP_IGNORE( iData->ExecuteActionL( aEventName , aParam ) );
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::IsActive
+//
+// ----------------------------------------------------------------------------
+//
+TBool CWrtDataPlugin::IsActive() const
+ {
+ return iPluginState == EResume;
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::IsStopped
+//
+// ----------------------------------------------------------------------------
+//
+TBool CWrtDataPlugin::IsStopped() const
+ {
+ return iPluginState == EStopped;
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::Data
+//
+// ----------------------------------------------------------------------------
+//
+CWrtData* CWrtDataPlugin::Data() const
+ {
+ return iData;
+ }
+
+// ----------------------------------------------------------------------------
+// CWrtDataPlugin::NetworkStatus
+//
+// ----------------------------------------------------------------------------
+//
+CWrtDataPlugin::TPluginNetworkStatus CWrtDataPlugin::NetworkStatus() const
+ {
+ return iNetworkStatus;
+ }
+
+// ---------------------------------------------------------------------------
+// CWrtDataPlugin::GetIdL
+// Gets the id of a content
+// ---------------------------------------------------------------------------
+//
+TInt CWrtDataPlugin::GetIdL( TDesC16& aObjectId)
+ {
+ TInt id = KErrNotFound;
+ HBufC16* objectId = HBufC16::NewLC( KAiContentIdMaxLength );
+ for( TInt i = 0;i< iDataCount; i++ )
+ {
+ objectId->Des().Copy((TUint16*)iContentModel[i].cid);
+ if( aObjectId == objectId->Des() )
+ {
+ id = iContentModel[i].id;
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( objectId );
+ return id;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CWrtDataPlugin::GetTypeL
+// Gets type of a content
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::GetTypeL(TDesC16& aObjectId, TDes16& aType )
+ {
+ HBufC16* objectId = HBufC16::NewLC( KAiContentIdMaxLength );
+ for( TInt i = 0;i< iDataCount; i++ )
+ {
+ objectId->Des().Copy((TUint16*)iContentModel[i].cid);
+ if( aObjectId == objectId->Des() )
+ {
+ if( iContentModel[i].type == KAiContentTypeText)
+ {
+ aType.Copy( KText );
+ }
+ else if( iContentModel[i].type == KAiContentTypeBitmap)
+ {
+ aType.Copy( KImage );
+ }
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( objectId );
+ }
+
+// ---------------------------------------------------------------------------
+//Refresh a specific image or text in the widget
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::RefreshL( TDesC16& aOperation, CLiwDefaultMap* aDataMap )
+ {
+ __PRINTS("*** CWrtDataPlugin::RefreshL ***");
+
+ __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x, operation: %S" ),
+ &PublisherInfo().Name(), PublisherInfo().Uid().iUid, &aOperation );
+
+ TInt observers( iObservers.Count() );
+ TInt transactionId = reinterpret_cast<TInt>( this );
+
+ for ( TInt obsIndex = 0; obsIndex < observers; obsIndex++ )
+ {
+ MAiContentObserver* observer = iObservers[obsIndex];
+
+ if ( observer->StartTransaction( transactionId ) == KErrNone )
+ {
+ if( ( aOperation == KOperationUpdate
+ || aOperation == KOperationAdd )
+ && aDataMap )
+ {
+ iData->PublishL( observer, aDataMap );
+ }
+ else if ( aOperation == KOperationDelete )
+ {
+ Clean( observer , EImage1 ) ;
+ }
+
+ observer->Commit( transactionId );
+ }
+
+ // Relese memory of the published text
+ iDataArray.ResetAndDestroy();
+ // Release memory of the published icons
+ iIconArray.Reset();
+ }
+
+ __PRINTS("*** CWrtDataPlugin::RefreshL - done ***");
+ }
+
+// ---------------------------------------------------------------------------
+// Publish a specific text of the widget
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::PublishTextL(MAiContentObserver* aObserver,
+ TInt aContentId, const TDesC16& aContentValue)
+ {
+ if ( aObserver->CanPublish( *this, aContentId , aContentId ) )
+ {
+ if( aContentValue.Length() > 0 )
+ {
+ HBufC* contentText = HBufC::NewLC(aContentValue.Size());
+ TPtr16 cDes = contentText->Des();
+ cDes.Copy(aContentValue);
+ aObserver->Publish( *this, aContentId, cDes, aContentId );
+ iDataArray.AppendL( contentText );
+ CleanupStack::Pop( contentText );
+ }
+ else
+ {
+ aObserver->Clean( *this, aContentId, aContentId );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Publish a specific image of the widget
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::PublishImageL(MAiContentObserver* aObserver,
+ TContentItem aContentId, const TDesC16& aPath )
+ {
+ TInt err = KErrNone;
+ TAknsItemID iconId;
+ iconId.iMajor=0;
+ iconId.iMinor=0;
+ TInt bitmapId(0);
+ TInt maskId(0);
+ TFileName fileName;
+ CGulIcon* icon = NULL;
+ CFbsBitmap* bitmap = NULL;
+ CFbsBitmap* mask = NULL;
+
+ if ( aObserver->CanPublish( *this, aContentId , aContentId ) )
+ {
+ TBool inSkin = ResolveSkinIdAndMifId( aPath, iconId, bitmapId, maskId, fileName );
+ if ( inSkin )
+ {
+ // Load from skin
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ if ( iconId.iMajor != 0 && iconId.iMajor!=0 )
+ {
+ // Create icon with fall back
+ TRAP_IGNORE(AknsUtils::CreateIconL(
+ skin,
+ iconId,
+ bitmap,
+ mask,
+ fileName, /* backup filename */
+ bitmapId, /* backup bit map id */
+ maskId)); /* backup mask id */
+ }
+ else if( bitmapId !=0 )
+ {
+ if ( maskId!=0 )
+ {
+ // Create icon from Mif filename , bitmap id and mask id
+ TRAP_IGNORE(icon = AknsUtils::CreateGulIconL(
+ skin,
+ iconId,
+ fileName,
+ bitmapId,
+ maskId) );
+ }
+ else
+ {
+ TRAP_IGNORE(AknsUtils::CreateIconL(
+ skin,
+ iconId,
+ bitmap,
+ fileName, /* backup filename */
+ bitmapId)); /* backup bit map id */
+ }
+ }
+
+ if ( icon == NULL && bitmap != NULL )
+ {
+ icon = CGulIcon::NewL( bitmap, mask );
+ }
+
+ if ( icon != NULL ) // Syntax correct but icon not found
+ {
+ aObserver->PublishPtr( *this, aContentId, icon , aContentId );
+ iIconArray.Append(icon);
+ }
+ else
+ {
+ err = KErrNotFound;
+ aObserver->Clean( *this, aContentId, aContentId );
+ }
+ }
+ else // Interpret as File path
+ {
+ RFile iconFile;
+
+ err = iconFile.Open( iRfs, aPath, EFileShareReadersOnly | EFileRead );
+
+ if( err == KErrNone )
+ {
+ aObserver->Publish( *this, aContentId, iconFile, aContentId );
+ }
+ else
+ {
+ aObserver->Clean( *this, aContentId, aContentId );
+ }
+
+ iconFile.Close();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Publish a image of the widget
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::PublishImageL(MAiContentObserver* aObserver,
+ TContentItem aContentId, TInt aHandle, TInt aMaskHandle )
+ {
+ if ( aObserver->CanPublish( *this, aContentId , aContentId ) )
+ {
+ if( aHandle != KErrBadHandle )
+ {
+ CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
+ if( KErrNone == bitmap->Duplicate( aHandle) )
+ {
+ // Take the ownership
+ CGulIcon* icon = CGulIcon::NewL(bitmap);
+ if( aMaskHandle != KErrBadHandle )
+ {
+ CFbsBitmap* mask = new (ELeave) CFbsBitmap();
+ if (KErrNone == mask->Duplicate( aMaskHandle) )
+ {
+ icon->SetMask( mask );
+ }
+ }
+ aObserver->PublishPtr( *this, aContentId, icon , aContentId );
+ iIconArray.Append(icon);
+ }
+ else
+ {
+ delete bitmap;
+ bitmap = NULL;
+ aObserver->Clean( *this, aContentId, aContentId );
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Cleans a data from the widget
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::Clean(MAiContentObserver* aObserver,
+ TInt aContentId )
+ {
+ if ( aObserver->CanPublish( *this, aContentId, aContentId ) )
+ {
+ aObserver->Clean( *this, aContentId, aContentId );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// Show the loading icong animation
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::ShowLoadingIcon(MAiContentObserver* aObserver)
+ {
+ aObserver->SetProperty( *this, KElement , KDisplay , KShow );
+ }
+
+// ---------------------------------------------------------------------------
+// Hides the loading icon animation
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::HideLoadingIcon(MAiContentObserver* aObserver)
+ {
+ aObserver->SetProperty( *this, KElement , KDisplay , KHide );
+
+ // Do not try to publish initial data anymore
+ StopTimer();
+ }
+
+// ---------------------------------------------------------------------------
+// Publishes widget's texts and images
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::PublishInitialDataL()
+ {
+ TInt observers( iObservers.Count() );
+ TInt transactionId = reinterpret_cast<TInt>( this );
+
+ for ( int i = 0; i < observers; i++ )
+ {
+ MAiContentObserver* observer = iObservers[i];
+
+ CleanupStack::PushL( TCleanupItem( CancelTransaction, observer ) );
+
+ if ( observer->StartTransaction( transactionId ) == KErrNone )
+ {// Publish default data
+ iData->PublishInitialDataL(observer);
+ observer->Commit( transactionId );
+ }
+
+ CleanupStack::Pop( observer );
+
+ // Release memory of the published text
+ iDataArray.ResetAndDestroy();
+ // Release memory of the published icons
+ iIconArray.Reset();
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// ResolveSkinItemId
+// ---------------------------------------------------------------------------
+//
+TBool CWrtDataPlugin::ResolveSkinIdAndMifId( const TDesC& aPath, TAknsItemID& aItemId,
+ TInt& abitmapId, TInt& aMaskId, TDes& aFilename )
+ {
+ // Syntax: skin( <major> <minor> ):mif(filename bimapId maskId)
+ TInt error = KErrNotFound;
+ TInt pos = aPath.FindF( KSkin );
+ if( pos != KErrNotFound )
+ {
+ // Skip skin token
+ pos += KSkin().Length();
+
+ // Initialize lexer
+ TLex lex( aPath.Mid( pos ) );
+ lex.SkipSpace();
+
+ // Check left parenthesis
+ if (lex.Get() == KLeftParenthesis )
+ {
+ //lex.SkipSpace();
+
+ TInt majorId( 0 );
+ TInt minorId( 0 );
+
+ // Resolve major id
+ error = lex.Val( majorId );
+
+ // Resolve minor id
+ lex.SkipSpace();
+ error |= lex.Val( minorId );
+
+ // initilize skin item id object
+ aItemId.Set( majorId, minorId );
+ }
+ }
+
+ if( (error == KErrNone && aPath.FindF( KColon ) != KErrNotFound )
+ || ( error == KErrNotFound ) )
+ {
+ error = KErrNotFound;
+ pos = aPath.FindF( KMif );
+ if ( pos != KErrNotFound )
+ {
+ pos += KMif().Length();
+ // Initialize lexer
+ TLex lex( aPath.Mid( pos ) );
+ lex.SkipSpace();
+
+ // Check left parenthesis
+ if (lex.Get() == KLeftParenthesis )
+ {
+ lex.SkipSpaceAndMark();
+ lex.SkipCharacters();
+ // Resolve MifFile name
+ aFilename.Copy(lex.MarkedToken());
+ if( aFilename.Length()!= 0)
+ {
+ // Resolve bitmap id
+ lex.SkipSpace();
+ error = lex.Val( abitmapId );
+
+ // Resolve mask id
+ // dont return error if it is not found, that is ok
+ lex.SkipSpace();
+ lex.Val( aMaskId );
+ }
+ else
+ {
+ error = KErrNotFound;
+ }
+ }
+ }
+ }
+ return (error == KErrNone );
+ }
+
+// ---------------------------------------------------------------------------
+// Cleanup callback for cancelling a transactions in case of leave
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::CancelTransaction( TAny* aObserver )
+ {
+ if ( aObserver )
+ {
+ MAiContentObserver* obs = reinterpret_cast< MAiContentObserver*>( aObserver );
+ TInt transactionId = reinterpret_cast<TInt>( aObserver );
+ obs->CancelTransaction( transactionId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Create and start republish timer
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::StartTimer()
+ {
+ TRAP_IGNORE(
+ if ( !iTimer )
+ {
+ iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+ }
+
+ if ( iTimer && !iTimer->IsActive() )
+ {
+ TTimeIntervalMicroSeconds32 delay( KTryAgainDelay );
+ iTimer->Start( delay, delay, TCallBack( Timeout, this ) );
+ }
+ );
+ }
+
+// ---------------------------------------------------------------------------
+// Cancel republish timer
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::CancelTimer()
+ {
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Stop and delete republish timer
+// ---------------------------------------------------------------------------
+//
+void CWrtDataPlugin::StopTimer()
+ {
+ if ( iTimer )
+ {
+ iTimer->Cancel();
+ delete iTimer;
+ iTimer = NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Initial data republish callback
+// ---------------------------------------------------------------------------
+//
+TInt CWrtDataPlugin::Timeout( TAny* aPtr )
+ {
+ CWrtDataPlugin* self = static_cast<CWrtDataPlugin*>( aPtr );
+
+ // Cancel timer before publishing
+ self->CancelTimer();
+
+ TInt observers( self->iObservers.Count() );
+ TInt transactionId = reinterpret_cast<TInt>( self );
+ TBool success( ETrue );
+
+ // Publish for each observer
+ for ( int i = 0; i < observers; i++ )
+ {
+ MAiContentObserver* observer = self->iObservers[i];
+
+ if ( observer->StartTransaction( transactionId ) == KErrNone )
+ {
+ // Publish default image
+ TRAPD( err, self->iData->PublishDefaultImageL( observer ) );
+ if ( KErrNone != err )
+ {
+ observer->CancelTransaction( transactionId );
+ success = EFalse;
+ }
+ else
+ {
+ //
+ observer->Commit( transactionId );
+ }
+ }
+ }
+
+ // Start timer again if there is error in publishing
+ if ( !success )
+ {
+ self->StartTimer();
+ }
+ else
+ {
+ self->StopTimer();
+ }
+
+ // Release memory of the published icons
+ self->iIconArray.Reset();
+
+ return KErrNone;
+ }
+
+
+
+// End of file