diff -r 000000000000 -r 96612d01cf9f videofeeds/server/IptvEpgManager/src/vcxgroupupdater.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videofeeds/server/IptvEpgManager/src/vcxgroupupdater.cpp Mon Jan 18 20:21:12 2010 +0200 @@ -0,0 +1,710 @@ +/* +* Copyright (c) 2008 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: Implements customised service update* +*/ + + + + +#include +#include +#include +#include // file helpers +#include "vcxgroupupdater.h" +#include "CIptvServer.h" +#include "CIptvEpgSession.h" +#include "CIptvService.h" +#include "IptvDebug.h" +#include "CIptvTimer.h" +#include "CIptvEpgService.h" +#include "CIptvEpgVodMsqQueue.h" + +const TInt KIptvVcfgFileParseWait( 500000 ); // 0.5 s +const TInt KIptvVcfgFileParseMaxTry( 10 ); // 5 s + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructors and destructors. +// --------------------------------------------------------------------------- +// +CVcxGroupUpdater* CVcxGroupUpdater::NewL( + CIptvServer& aServer, + CIptvEpgSession& aSession, + CIptvEpgVodMsqQueue& aMsgQueue ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::NewL" ); + + CVcxGroupUpdater* self = + new( ELeave ) CVcxGroupUpdater( aServer, aSession, aMsgQueue ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +CVcxGroupUpdater::CVcxGroupUpdater( + CIptvServer& aServer, + CIptvEpgSession& aSession, + CIptvEpgVodMsqQueue& aMsgQueue ) : + iServer( aServer ), + iSession( aSession ), + iMsgQueue( aMsgQueue ), + iCurrentAction( CIptvEpgPluginInterface::EIptvRssNone ) + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::CVcxGroupUpdater" ); + } + +void CVcxGroupUpdater::ConstructL() + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::ConstructL" ); + + User::LeaveIfError( iFs.Connect() ); + } + +CVcxGroupUpdater::~CVcxGroupUpdater() + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::~CVcxGroupUpdater" ); + + if ( iVcfgParseTimer ) + { + iVcfgParseTimer->Cancel(); + delete iVcfgParseTimer; + } + + delete iDownloadedVcfgPath; + delete iPlugin; + REComSession::FinalClose(); + + iFs.Close(); + } + +// --------------------------------------------------------------------------- +// Start download. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::StartGroupUpdateL( CIptvEpgService* aService ) + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::StartGroupDownloadL - enter" ); + + iLocalValid = EFalse; + + // Create download plugin. + if ( iPlugin ) + { + delete iPlugin; + iPlugin = NULL; + REComSession::FinalClose(); + } + + if ( !iPlugin ) + { + iPlugin = CIptvEpgPluginInterface::NewL( aService->iUid ); + } + + iCurrentGroupServiceId = aService->iServiceId; + iDownloadStartTime.UniversalTime(); + + // Initialize download plugin. + iPlugin->SetVodCallback( this ); + iCurrentAction = CIptvEpgPluginInterface::EIptvRssServiceGroup; + iPlugin->SetServiceInformationL( aService, iCurrentAction ); + + // Start actual download. + iPlugin->RunPlugin(); + + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::StartDownloadL - exit" ); + } + +// --------------------------------------------------------------------------- +// Cancel current download download, if any. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::CancelGroupUpdate() + { + IPTVLOGSTRING3_LOW_LEVEL( + "CVcxGroupUpdater::CancelGroupUpdate -- %d/%d", + iPluginRunning, + iCurrentAction ); + + if ( iPlugin ) + { + delete iPlugin; + iPlugin = NULL; + REComSession::FinalClose(); + } + + iPluginRunning = EFalse; + iCurrentAction = CIptvEpgPluginInterface::EIptvRssNone; + } + +// --------------------------------------------------------------------------- +// Enquire is download ongoing. +// --------------------------------------------------------------------------- +// +TBool CVcxGroupUpdater::IsGroupUpdateOngoing() + { + IPTVLOGSTRING2_LOW_LEVEL( + "CVcxGroupUpdater::IsGroupUpdateOngoing -- %d", + iPluginRunning ); + + return iPluginRunning; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::StartedL() + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::StartedL -- Rss Plugin started" ); + + iPluginRunning = ETrue; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::ContentUpdateCompletedL() + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::ContentUpdateCompletedL" ); + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::FinishedL( + TTime& /* aUpdateInterval */ ) + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::FinishedL -- Rss Plugin finished" ); + + iPluginRunning = EFalse; + iCurrentAction = CIptvEpgPluginInterface::EIptvRssNone; + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::AddCategoryL( + CIptvEpgCategory& /* aCategory */, + TUint32& /* aCategoryKey */ ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::AddCategoryL" ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::AddContentL( + CIptvEpgContent& /* aContent */, + RPointerArray /* aMediaContents */, + TUint32& /* aContentKey */ ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::AddContentL" ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::UpdateServiceThumbnailL( + TDesC& aFilePath, + const TBool aGrouped ) + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater::UpdateServiceThumbnailL" ); + + // Also VCFG file download is indicated here. + if ( CIptvEpgPluginInterface::EIptvRssServiceGroup == iCurrentAction ) + { + StartVcfgFileParseL( aFilePath ); + } + else + { + iSession.UpdateServiceThumbnailL( aFilePath, aGrouped ); + } + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::AddRelationL( + TUint32& /* aCategoryKey */, + TUint32& /* aContentKey */ ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::AddRelationL" ); + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::ErrorL( + TInt aError, + TInt aInfo ) + { + IPTVLOGSTRING3_HIGH_LEVEL( + "CVcxGroupUpdater::ErrorL( %d, %d )", aError, aInfo ); + +#ifdef _DEBUG + + switch ( aError ) + { + case KIptvContentUpdateCompleted: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvContentUpdateCompleted" ); + break; + case KIptvServiceThumbnailDownloaded: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvServiceThumbnailDownloaded" ); + break; + case KIptvThumbnailCount: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvThumbnailCount" ); + break; + case KIptvRssSearchThumbnailCount: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvRssSearchThumbnailCount" ); + break; + case KIptvErrorEpgUpdateSuccessed: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvErrorEpgUpdateSuccessed" ); + break; + case KIptvErrorRssSearchSucceed: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvErrorRssSearchSucceed" ); + break; + case KIptvContentThumbnailDownloaded: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvContentThumbnailDownloaded" ); + break; + case KIptvRssSearchContentThumbnailDownloaded: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvRssSearchContentThumbnailDownloaded" ); + break; + case KIptvErrorEpgUpdateFailed: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvErrorEpgUpdateFailed" ); + break; + case KIptvErrorRssSearchFailed: + IPTVLOGSTRING_HIGH_LEVEL( " -- KIptvErrorRssSearchFailed" ); + break; + default: + IPTVLOGSTRING_HIGH_LEVEL( " -- Unknown" ); + } + +#endif // _DEBUG + + if ( ( KIptvContentUpdateCompleted == aError ) && + ( EIptvDlNoErrorUpToDate == aInfo ) ) + { + IPTVLOGSTRING_HIGH_LEVEL( " -- Local VCFG-file valid" ); + iLocalValid = ETrue; + } + else + { + if ( ( KIptvErrorEpgUpdateSuccessed == aError ) && + ( KErrNone == aInfo ) ) + { + +#ifdef _DEBUG + + // Debug print last updated info. + TBuf lastModifiedDatePrint; + _LIT( KIptvDatePrint, "%D%M%Y%/0%1%/1%2%/2%3%/3" ); + iDownloadStartTime.FormatL( lastModifiedDatePrint, KIptvDatePrint ); + + TBuf lastModifiedTimePrint; + _LIT( KIptvTimePrint, "%-B%:0%J%:1%T%:2%S%.%*C4%:3%+B" ); + iDownloadStartTime.FormatL( lastModifiedTimePrint, KIptvTimePrint ); + + IPTVLOGSTRING3_LOW_LEVEL( " -- Group update ok, last modified set: %S %S", + &lastModifiedDatePrint, + &lastModifiedTimePrint ); + +#endif // _DEBUG + + SetLastModifiedL( iCurrentGroupServiceId, iDownloadStartTime ); + } + + // Inform clients about failure. + iMsgQueue.SendMessageToClientL( aError, aInfo ); + } + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::UpdateCategoryIconL( + TUint32& /* aCategoryKey */, + TUint32& /* aIconFileId */, + TDesC& /* aIconFilePath */, + TBool /* aIsUrl */ ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::UpdateCategoryIconL" ); + + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// From MIptvEpgVodCallback interface +// --------------------------------------------------------------------------- +// +TInt CVcxGroupUpdater::UpdateContentIconL( + TUint32& aContentKey, + TUint32& /* aIconFileId */, + TDesC& aIconFilePath, + TBool /* aIsUrl */ ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::UpdateContentIconL" ); + + // Update icon pathname to service. + CIptvService* service = iServer.iServiceManager->GetServiceL( + aContentKey, ETrue /* do open/close */ ); + if ( service ) + { + CleanupStack::PushL( service ); // 1-> + service->SetIconPath( aIconFilePath ); + iServer.iServiceManager->UpdateServiceL( *service ); + CleanupStack::PopAndDestroy( service ); //<-1 + return KErrNone; + } + + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Starts parsing of downloaded VCFG file. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::StartVcfgFileParseL( + const TDesC& aPathName ) + { + IPTVLOGSTRING_HIGH_LEVEL( + "CVcxGroupUpdater::StartVcfgFileParseL" ); + + TInt error( KErrNone ); + + if ( iLocalValid ) + { + iMsgQueue.SendMessageToClientL( + KIptvContentUpdateCompleted, + EIptvDlNoErrorUpToDate ); + } + else + { + // Save file name for deletion. + if ( iDownloadedVcfgPath ) + { + delete iDownloadedVcfgPath; + iDownloadedVcfgPath = NULL; + } + + iDownloadedVcfgPath = aPathName.AllocL(); + + // Clear vcfg received flag + SetNotParsedL( iCurrentGroupServiceId ); + + // Send vcfg to provision + RApaLsSession ls; + error = ls.Connect(); + if ( error == KErrNone ) + { + // Get UID of application which handles this type of file + TUid appUid( TUid::Null() ); + TDataType dataType( appUid ); + error = ls.AppForDocument( aPathName, appUid, dataType ); + if ( appUid == KNullUid ) + { + error = KErrNotSupported; + } + + // Start application + if ( error == KErrNone ) + { + TThreadId id( 0 ); + error = ls.StartDocument( aPathName, appUid, id ); + } + + ls.Close(); + } + } + + if ( error == KErrNone ) + { + // Start timer to wait provision parsing + if ( !iVcfgParseTimer ) + { + iVcfgParseTimer = + CIptvTimer::NewL( CActive::EPriorityStandard, *this ); + } + + if ( !iVcfgParseTimer->IsActive() ) + { + iVcfgParseTimer->After( KIptvVcfgFileParseWait ); + } + + iVcfgParseMaxCount = KIptvVcfgFileParseMaxTry; + } + else + { + // Notfy immediately on error case + iMsgQueue.SendMessageToClientL( + KIptvContentUpdateCompleted, + error ); + iPluginRunning = EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CVcxGroupUpdater::TimerExpired +// ----------------------------------------------------------------------------- +// +void CVcxGroupUpdater::TimerExpired( CIptvTimer* aTimer ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::TimerExpired()" ); + + TRAPD( err, DoTimerExpiredL( aTimer ) ); + if ( err != KErrNone ) + { + IPTVLOGSTRING2_LOW_LEVEL( + "CVcxGroupUpdater::DoTimerExpiredL leaved (%d)", + err ); + } + } + +// ----------------------------------------------------------------------------- +// CVcxGroupUpdater::DoTimerExpiredL +// ----------------------------------------------------------------------------- +// +void CVcxGroupUpdater::DoTimerExpiredL( CIptvTimer* aTimer ) + { + IPTVLOGSTRING_LOW_LEVEL( "CVcxGroupUpdater::DoTimerExpiredL()" ); + + // %% How about parse really failed... + if ( aTimer == iVcfgParseTimer ) + { + TBool completed( EFalse ); + + if ( iLocalValid ) + { + // Parsing not needed. + completed = ETrue; + iLocalValid = EFalse; + StartThumbnailDownloadL(); + } + else if ( IsServiceParsed( iCurrentGroupServiceId ) ) + { + // Parsing complete. + iMsgQueue.SendMessageToClientL( + KIptvContentUpdateCompleted, + KErrNone ); + completed = ETrue; + StartThumbnailDownloadL(); + } + else if ( 0 < iVcfgParseMaxCount-- ) + { + // Continue to wait parsing complete. + if ( !iVcfgParseTimer->IsActive() ) + { + iVcfgParseTimer->After( KIptvVcfgFileParseWait ); + } + } + else + { + IPTVLOGSTRING_LOW_LEVEL( + "CVcxGroupUpdater:: NotifySingleFileDownloadCompleteL timeout" ); + iMsgQueue.SendMessageToClientL( + KIptvErrorEpgUpdateFailed, + KIptvRssParserError ); + completed = ETrue; + iPluginRunning = EFalse; + } + + // Parsed file is no more needed, so delete it. + if ( completed && iDownloadedVcfgPath ) + { + if ( BaflUtils::FileExists( iFs, iDownloadedVcfgPath->Des() ) ) + { + iFs.Delete( iDownloadedVcfgPath->Des() ); + } + + delete iDownloadedVcfgPath; + iDownloadedVcfgPath = NULL; + } + } + } + +// --------------------------------------------------------------------------- +// Initialize VCFG provision done flag. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::SetNotParsedL( + TUint32 aServiceId ) + { + IPTVLOGSTRING_HIGH_LEVEL( "CVcxGroupUpdater::SetNotParsedL" ); + + // Set parsing status of service. + CIptvService* service( NULL ); + service = iServer.iServiceManager->GetServiceL( + aServiceId, ETrue /* do open/close */ ); + if ( service ) + { + CleanupStack::PushL( service ); // 1-> + service->SetFlags( + service->GetFlags() & ~CIptvService::EGroupReceived ); + iServer.iServiceManager->UpdateServiceL( *service ); + CleanupStack::PopAndDestroy( service ); //<-1 + } + } + +// --------------------------------------------------------------------------- +// Indication of VCFG file download completion. +// --------------------------------------------------------------------------- +// +TBool CVcxGroupUpdater::IsServiceParsed( + TUint32 aServiceId ) + { + IPTVLOGSTRING_HIGH_LEVEL( "CVcxGroupUpdater::IsServiceParsed" ); + + TBool parsed( EFalse ); + + // Get parsing status of service. + CIptvService* service( NULL ); + TRAPD( err, service = iServer.iServiceManager->GetServiceL( + aServiceId, ETrue /* do open/close */ ) ); + if ( service ) + { + if ( KErrNone == err ) + { + parsed = ( service->GetFlags() & CIptvService::EGroupReceived ) > 0; + } + + delete service; + } + + return parsed; + } + +// --------------------------------------------------------------------------- +// Set service Last Modified. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::SetLastModifiedL( + TUint32 aServiceId, + TTime aLastModified ) + { + IPTVLOGSTRING_HIGH_LEVEL( "CVcxGroupUpdater::SetLastModifiedL" ); + + CIptvService* service( NULL ); + service = iServer.iServiceManager->GetServiceL( + aServiceId, ETrue /* do open/close */ ); + if ( service ) + { + CleanupStack::PushL( service ); // 1-> + service->SetEpgUpdateTimeL( aLastModified ); + iServer.iServiceManager->UpdateServiceL( *service ); + CleanupStack::PopAndDestroy( service ); //<-1 + } + } + +// --------------------------------------------------------------------------- +// Collect list of required thumbnails and start download. +// --------------------------------------------------------------------------- +// +void CVcxGroupUpdater::StartThumbnailDownloadL() + { + if ( iPlugin ) + { + // Service group thumbnail + TUint32 groupId( 0 ); + TInt thumbnailCount( 0 ); + CIptvService* tempService = iServer.iServiceManager->GetServiceL( + iCurrentGroupServiceId, ETrue /* do open/close */ ); + if ( tempService ) + { + CleanupStack::PushL( tempService );// 1-> + + CIptvEpgService* service = CIptvEpgService::NewL(); + CleanupStack::PushL( service ); // 2-> + service->iAddress.Copy( tempService->GetIconUrl() ); + service->iServiceId = tempService->GetId(); + + thumbnailCount++; + groupId = tempService->GetGroupId(); + iPlugin->SetServiceInformationL( + service, + CIptvEpgPluginInterface::EIptvRssAddServiceThumbnailToDlQueue ); + + CleanupStack::PopAndDestroy( service ); //<-2 + CleanupStack::PopAndDestroy( tempService ); //<-1 + } + + iCurrentAction = + CIptvEpgPluginInterface::EIptvRssAddServiceThumbnailToDlQueue; + // For each sub service thumbnail + CIptvServices* services = iServer.iServiceManager->GetServicesL( + CIptvServiceManagementClient::EGroupedServices, + CIptvServiceManagementClient::EDisplayOrderDescending, + 0 /*Latest*/ ); + if ( services ) + { + CleanupStack::PushL( services ); // 1-> + + // Find all services matching to group. + for ( TInt i( services->Count() - 1 ); i >= 0 ; i-- ) + { + tempService = services->GetServiceL( i ); + CleanupStack::PushL( tempService ); // 2-> + + // Verify group id + if ( groupId == tempService->GetGroupId() ) + { + CIptvEpgService* service = CIptvEpgService::NewL(); + CleanupStack::PushL( service ); // 3-> + service->iAddress.Copy( tempService->GetIconUrl() ); + service->iServiceId = tempService->GetId(); + + thumbnailCount++; + iPlugin->SetServiceInformationL( + service, + CIptvEpgPluginInterface::EIptvRssAddItemThumbnailToDlQueue ); + + CleanupStack::PopAndDestroy( service ); //<-3 + } + + CleanupStack::PopAndDestroy( tempService ); //<-2 + } + + CleanupStack::PopAndDestroy( services ); //<-1 + } + + iMsgQueue.SendMessageToClientL( KIptvThumbnailCount, thumbnailCount ); + iPlugin->RunPlugin(); + } + }