videofeeds/server/IptvScheduledDownload/src/iptvvodscheduleddownloadactivescheduler.cpp
changeset 0 96612d01cf9f
equal deleted inserted replaced
-1:000000000000 0:96612d01cf9f
       
     1 /*
       
     2 * Copyright (c) 2006 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:    Scheduled download scheduler active object.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 #include <ipvideo/CCseScheduledProgram.h>
       
    21 #include <ipvideo/CCseSchedulerAPI.h>
       
    22 #include "IptvDebug.h"
       
    23 #include <e32math.h>
       
    24 #include <s32mem.h>
       
    25 #include "IptvEngineUids.h"
       
    26 
       
    27 #include "iptvvodscheduleddownloadactivescheduler.h"
       
    28 #include "iptvvodscheduleddownloadscheduler.h"
       
    29 
       
    30 // CONSTANTS
       
    31 const TInt KIptvNumberOfDaysToSchedule(7);  //  Days to schedule
       
    32 const TInt KIptvMorningStartHour = 6;
       
    33 const TInt KIptvNoonStartHour = 11;
       
    34 const TInt KIptvAfternoonStartHour = 13;
       
    35 const TInt KIptvEveningStartHour = 18;
       
    36 const TInt KIptvTenPercentDivider = 10;
       
    37 const TInt KIptvTwiceTenPercent = 2;
       
    38 
       
    39 //#define RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    40 
       
    41 #ifdef RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    42 #warning The scheduled download test flag has been defined! Do not release this build!
       
    43 const TInt KIptvDayMonthAdvance = 1;
       
    44 #endif // RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    45 
       
    46 #if defined(_DEBUG) && ! defined(RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC)
       
    47 const TInt KIptvDayMonthAdvanceDebug = 1;
       
    48 #endif // _DEBUG && ! RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    49 
       
    50 #ifdef RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    51 const TInt KIptv30SecondsStartDelay = 30;
       
    52 const TInt Kiptv60MinutesTestSlot = 60;
       
    53 #endif // RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
    54 
       
    55 #if defined(RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC) || defined(_DEBUG)
       
    56 const TInt KIptvDebugStringLength = 80;
       
    57 #endif // RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC || _DEBUG
       
    58 
       
    59 // -----------------------------------------------------------------------------
       
    60 // CIptvVODScheduledDownloadActiveScheduler::CIptvVODScheduledDownloadActiveScheduler
       
    61 // C++ default constructor can NOT contain any code, that
       
    62 // might leave.
       
    63 // -----------------------------------------------------------------------------
       
    64 //
       
    65 CIptvVODScheduledDownloadActiveScheduler::CIptvVODScheduledDownloadActiveScheduler(
       
    66         CIptvVODScheduledDownloadScheduler& aScheduler,
       
    67         TIptvServiceId aServiceId,
       
    68         TIptvVodScheduleConnectionCondition aNetworkCondition,
       
    69         TIptvVodScheduleDownloadtimeCombination aDownloadTime,
       
    70         TIptvVodScheduleDownloadTypeCombination aDownloadType )
       
    71         : CTimer( EPriorityNormal ), iScheduler( aScheduler ),
       
    72             iServiceId( aServiceId ), iNetworkCondition( aNetworkCondition ),
       
    73             iDownloadTime( aDownloadTime ), iDownloadType( aDownloadType )
       
    74     {
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CIptvVODScheduledDownloadActiveScheduler::ConstructL
       
    79 // Symbian 2nd phase constructor can leave.
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 void CIptvVODScheduledDownloadActiveScheduler::ConstructL()
       
    83     {
       
    84 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::ConstructL()");
       
    85 
       
    86     CTimer::ConstructL();
       
    87     CActiveScheduler::Add ( this );
       
    88 
       
    89 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::ConstructL()");
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // CIptvVODScheduledDownloadActiveScheduler::NewL
       
    94 // Two-phased constructor.
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 CIptvVODScheduledDownloadActiveScheduler* CIptvVODScheduledDownloadActiveScheduler::NewL(
       
    98         CIptvVODScheduledDownloadScheduler& aScheduler,
       
    99         TIptvServiceId aServiceId,
       
   100         TIptvVodScheduleConnectionCondition aNetworkCondition,
       
   101         TIptvVodScheduleDownloadtimeCombination aDownloadTime,
       
   102         TIptvVodScheduleDownloadTypeCombination aDownloadType )
       
   103     {
       
   104 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::NewL()");
       
   105     CIptvVODScheduledDownloadActiveScheduler* self =
       
   106         new( ELeave ) CIptvVODScheduledDownloadActiveScheduler(
       
   107             aScheduler,
       
   108             aServiceId,
       
   109             aNetworkCondition,
       
   110             aDownloadTime,
       
   111             aDownloadType );
       
   112 
       
   113     CleanupStack::PushL( self );
       
   114     self->ConstructL();
       
   115     CleanupStack::Pop( self );
       
   116 
       
   117 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::NewL()");
       
   118 
       
   119     return self;
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // Destructor
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 CIptvVODScheduledDownloadActiveScheduler::~CIptvVODScheduledDownloadActiveScheduler()
       
   127     {
       
   128 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::~CIptvVODScheduledDownloadActiveScheduler()");
       
   129 
       
   130     //  Remove us from the list
       
   131     iScheduler.RemoveActive( this );
       
   132 
       
   133     delete iCse;
       
   134     iScheduledDownloads.ResetAndDestroy();
       
   135 
       
   136 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::~CIptvVODScheduledDownloadActiveScheduler()");
       
   137     }
       
   138 
       
   139 
       
   140 // -----------------------------------------------------------------------------
       
   141 // CIptvVODScheduledDownloadActiveScheduler::RunL
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 void CIptvVODScheduledDownloadActiveScheduler::RunL()
       
   145     {
       
   146 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::RunL()");
       
   147 
       
   148     CleanupStack::PushL( this );
       
   149 
       
   150     //  This must be done here and not in the constructor, because the plugin
       
   151     //  will cause the creation of this instance and the next call will cause
       
   152     //  deadlock if this is in the constructor
       
   153     if (!iCse)
       
   154         {
       
   155         iCse = CCseSchedulerApi::NewL();
       
   156         }
       
   157 
       
   158     TRAP_IGNORE( UpdateScheduleL() );
       
   159 
       
   160     //  This will DESTROY us, don't do anything after this
       
   161     CleanupStack::PopAndDestroy( this );
       
   162 
       
   163 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::RunL()");
       
   164     }
       
   165 
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // CIptvVODScheduledDownloadActiveScheduler::UpdateScheduleL
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 void CIptvVODScheduledDownloadActiveScheduler::UpdateScheduleL()
       
   172     {
       
   173 	IPTVLOGSTRING2_HIGH_LEVEL("CIptvVODScheduledDownloadActiveScheduler::UpdateScheduleL(), service %d", iServiceId);
       
   174 
       
   175     //  Just in case, reset the schedules
       
   176     iScheduledDownloads.ResetAndDestroy();
       
   177 
       
   178     //  Get current schedules
       
   179     User::LeaveIfError(
       
   180         iCse->GetSchedulesByPluginUid(
       
   181             KIptvScheduledDownloadPluginImplementationUid,
       
   182             iScheduledDownloads ) );
       
   183 
       
   184     //  Remove from array schedules which are not for this service or app uid
       
   185     for (TInt i = iScheduledDownloads.Count() - 1; i >= 0; i--)
       
   186         {
       
   187         if (GetServiceIdFromScheduledProgramL( *(iScheduledDownloads[i] ) ) !=
       
   188             iServiceId || iScheduledDownloads[i]->AppUid() != IPTV_SERVER_UID)
       
   189             {
       
   190             delete iScheduledDownloads[i];
       
   191             iScheduledDownloads.Remove( i );
       
   192             }
       
   193         }
       
   194 
       
   195     //  If manual update, no schedule or no download,
       
   196     //  remove all schedules from CSE
       
   197     if (iNetworkCondition  == EManual ||
       
   198         iDownloadTime == ENoSchedule ||
       
   199         iDownloadType == ENoDownload)
       
   200         {
       
   201     	IPTVLOGSTRING_HIGH_LEVEL("CIptvVODScheduledDownloadActiveScheduler::UpdateScheduleL() removing all schedules");
       
   202 
       
   203         //  Remove all schedules
       
   204         for (TInt i = 0; i < iScheduledDownloads.Count(); i++)
       
   205             {
       
   206             User::LeaveIfError( iCse->RemoveSchedule(
       
   207                     iScheduledDownloads[i]->DbIdentifier() ) );
       
   208             }
       
   209         }
       
   210     else
       
   211         {
       
   212         //  Reschedule the schedules
       
   213         ReScheduleL();
       
   214         }
       
   215 
       
   216     iScheduledDownloads.ResetAndDestroy();
       
   217 
       
   218 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::UpdateScheduleL()");
       
   219     }
       
   220 
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // CIptvVODScheduledDownloadActiveScheduler::ReScheduleL
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 void CIptvVODScheduledDownloadActiveScheduler::ReScheduleL()
       
   227     {
       
   228 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::ReScheduleL()");
       
   229 
       
   230     //  Create all time slots
       
   231     RArray<TScheduleSlot> scheduleSlots;
       
   232     CleanupClosePushL(scheduleSlots);
       
   233     BuildScheduleSlotsL( scheduleSlots );
       
   234 
       
   235     //  Go through the scheduled downloads, try to find a place for them
       
   236     for (TInt i = 0; i < iScheduledDownloads.Count(); i++)
       
   237         {
       
   238         CCseScheduledProgram* schedule = iScheduledDownloads[i];
       
   239         TTime& scheduleTime = schedule->StartTime();
       
   240 
       
   241         //  Go through the schedule slots and
       
   242         //  try to find place for the schedule
       
   243         for (TInt j = 0; j < scheduleSlots.Count(); j++)
       
   244             {
       
   245             TScheduleSlot& slot = scheduleSlots[j];
       
   246             if (slot.iStartTime <= scheduleTime &&
       
   247                 slot.iEndTime > scheduleTime)
       
   248                 {
       
   249                 //  Slot found, we can finish the loop after handling this
       
   250                 j = scheduleSlots.Count();
       
   251 
       
   252                 //  Should there be a schedule and if so, is it empty
       
   253                 if (slot.iShouldHaveSchedule && !slot.iAlreadyHasSchedule)
       
   254                     {
       
   255                     //  Suitable empty slot found
       
   256                     slot.iAlreadyHasSchedule = ETrue;
       
   257                     }
       
   258                 else
       
   259                     {
       
   260                     //  Slot should not have schedule or it already has a
       
   261                     //  schedule, cancel this
       
   262                     User::LeaveIfError(
       
   263                         iCse->RemoveSchedule( schedule->DbIdentifier() ) );
       
   264                     }
       
   265                 }
       
   266             }
       
   267         }
       
   268 
       
   269 #ifdef RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC  //  this is just for test
       
   270 
       
   271         CCseScheduledProgram*   newSchedule = CCseScheduledProgram::NewL();
       
   272         CleanupStack::PushL( newSchedule );
       
   273 
       
   274         TTime start;
       
   275         start.UniversalTime();
       
   276         start += TTimeIntervalSeconds( KIptv30SecondsStartDelay );
       
   277 
       
   278         newSchedule->SetStartTime( start );
       
   279         start += TTimeIntervalMinutes( Kiptv60MinutesTestSlot );
       
   280         newSchedule->SetEndTime( start );
       
   281         newSchedule->SetAppUid( IPTV_SERVER_UID );
       
   282         newSchedule->SetPluginUid(
       
   283                 KIptvScheduledDownloadPluginImplementationUid );
       
   284         newSchedule->SetScheduleType(
       
   285                 CCseScheduledProgram::ECseScheduleDownload );
       
   286         HBufC8* data = WriteApplicationDataL();
       
   287         CleanupStack::PushL( data );
       
   288         newSchedule->SetApplicationDataL( data->Des() );
       
   289         CleanupStack::PopAndDestroy( data );
       
   290 
       
   291         User::LeaveIfError( iCse->AddSchedule( *newSchedule ) );
       
   292 
       
   293         TDateTime date( start.DateTime() );
       
   294         _LIT( KTimeFormat, "Scheduled download for service %d at %d.%d.%d %d:%d, 30s test schedule" );
       
   295         TBuf<KIptvDebugStringLength> buffer;
       
   296         buffer.Format(
       
   297                 KTimeFormat,
       
   298                 iServiceId,
       
   299                 date.Day() + KIptvDayMonthAdvance,
       
   300                 date.Month() + KIptvDayMonthAdvance,
       
   301                 date.Year(),
       
   302                 date.Hour(),
       
   303                 date.Minute() );
       
   304         IPTVLOGTEXT_HIGH_LEVEL( buffer );
       
   305 
       
   306         CleanupStack::PopAndDestroy( newSchedule );
       
   307 
       
   308 #else //  RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC, this is normal case
       
   309 
       
   310     //  All schedules in the CSE have been checked,
       
   311     //  now check if we need to add
       
   312     for (TInt k = 0; k < scheduleSlots.Count(); k++)
       
   313         {
       
   314         TScheduleSlot& slot = scheduleSlots[k];
       
   315 
       
   316         //  Should we have schedule here and we don't have
       
   317         if (slot.iShouldHaveSchedule && !slot.iAlreadyHasSchedule)
       
   318             {
       
   319             //  We need to add new schedule here
       
   320             CCseScheduledProgram*   newSchedule =
       
   321                     CCseScheduledProgram::NewL();
       
   322             CleanupStack::PushL( newSchedule );
       
   323             //  Randomize the run time
       
   324             newSchedule->SetStartTime( RandomizeRunTime( slot ) );
       
   325             newSchedule->SetEndTime( slot.iEndTime );
       
   326             newSchedule->SetAppUid( IPTV_SERVER_UID );
       
   327             newSchedule->SetPluginUid(
       
   328                     KIptvScheduledDownloadPluginImplementationUid );
       
   329             newSchedule->SetScheduleType(
       
   330                     CCseScheduledProgram::ECseScheduleDownload );
       
   331             HBufC8* data = WriteApplicationDataL();
       
   332             CleanupStack::PushL( data );
       
   333             newSchedule->SetApplicationDataL( data->Des() );
       
   334             CleanupStack::PopAndDestroy( data );
       
   335 
       
   336             User::LeaveIfError( iCse->AddSchedule( *newSchedule ) );
       
   337 
       
   338 #ifdef _DEBUG
       
   339             //  Print time for debugging purpose
       
   340             TDateTime date( newSchedule->StartTime().DateTime() );
       
   341             _LIT( KTimeFormat, "Scheduled download for service %d at %d.%d.%d %d:%d" );
       
   342             TBuf<KIptvDebugStringLength> buffer;
       
   343             buffer.Format(
       
   344                     KTimeFormat,
       
   345                     iServiceId,
       
   346                     date.Day() + KIptvDayMonthAdvanceDebug,
       
   347                     date.Month() + KIptvDayMonthAdvanceDebug,
       
   348                     date.Year(),
       
   349                     date.Hour(),
       
   350                     date.Minute() );
       
   351 	        IPTVLOGTEXT_HIGH_LEVEL( buffer );
       
   352 #endif
       
   353 
       
   354             CleanupStack::PopAndDestroy( newSchedule );
       
   355             }
       
   356         }
       
   357 
       
   358 #endif  //  RD_IPTV_FEA_SCHEDULE_DOWNLOAD_IN_30_SEC
       
   359 
       
   360     CleanupStack::PopAndDestroy( &scheduleSlots );
       
   361 
       
   362 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::ReScheduleL()");
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CIptvVODScheduledDownloadActiveScheduler::BuildScheduleSlotsL
       
   367 // -----------------------------------------------------------------------------
       
   368 //
       
   369 void CIptvVODScheduledDownloadActiveScheduler::BuildScheduleSlotsL(
       
   370         RArray<TScheduleSlot>& aScheduleSlots ) const
       
   371     {
       
   372 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::BuildScheduleSlotsL()");
       
   373 
       
   374     TTime now;
       
   375     now.UniversalTime();
       
   376     TTime homeNow;
       
   377     homeNow.HomeTime();
       
   378     TTimeIntervalMicroSeconds homeUtcDiff = homeNow.MicroSecondsFrom( now );
       
   379 
       
   380     aScheduleSlots.Reset();
       
   381 
       
   382     //  Set the seconds, minutes and micros to zero
       
   383     TDateTime start = now.DateTime();
       
   384     start.SetMinute( 0 );
       
   385     start.SetSecond( 0 );
       
   386     start.SetMicroSecond( 0 );
       
   387 
       
   388     //  Set slot start time for today in correct time
       
   389     start.SetHour( 0 );
       
   390     TTime night( start );
       
   391     night -= homeUtcDiff; //  change to UTC
       
   392 
       
   393     start.SetHour( KIptvMorningStartHour );
       
   394     TTime morning( start );
       
   395     morning -= homeUtcDiff; //  change to UTC
       
   396 
       
   397     start.SetHour( KIptvNoonStartHour );
       
   398     TTime noon( start );
       
   399     noon -= homeUtcDiff; //  change to UTC
       
   400 
       
   401     start.SetHour( KIptvAfternoonStartHour );
       
   402     TTime afternoon( start );
       
   403     afternoon -= homeUtcDiff; //  change to UTC
       
   404 
       
   405     start.SetHour( KIptvEveningStartHour );
       
   406     TTime evening( start );
       
   407     evening -= homeUtcDiff; //  change to UTC
       
   408 
       
   409     //  Create slots for KIptvNumberOfDaysToSchedule days
       
   410     for (TInt i = 0; i < KIptvNumberOfDaysToSchedule; i++)
       
   411         {
       
   412         User::LeaveIfError( aScheduleSlots.Append(
       
   413                 TScheduleSlot( night, morning, iDownloadTime & ENight ) ) );
       
   414         User::LeaveIfError( aScheduleSlots.Append(
       
   415                 TScheduleSlot( morning, noon, iDownloadTime & EMorning ) ) );
       
   416         User::LeaveIfError( aScheduleSlots.Append(
       
   417                 TScheduleSlot( noon, afternoon, iDownloadTime & ENoon ) ) );
       
   418         User::LeaveIfError( aScheduleSlots.Append(
       
   419                 TScheduleSlot(
       
   420                     afternoon,
       
   421                     evening,
       
   422                     iDownloadTime & EAfternoon ) ) );
       
   423         User::LeaveIfError( aScheduleSlots.Append(
       
   424                 TScheduleSlot(
       
   425                     evening,
       
   426                     night + TTimeIntervalDays(1),
       
   427                     iDownloadTime & EEvening ) ) );
       
   428 
       
   429         //  Advance one day
       
   430         night += TTimeIntervalDays(1);
       
   431         morning += TTimeIntervalDays(1);
       
   432         noon += TTimeIntervalDays(1);
       
   433         afternoon += TTimeIntervalDays(1);
       
   434         evening += TTimeIntervalDays(1);
       
   435         }
       
   436 
       
   437     //  Some schedules may be in the past, remove them
       
   438     for (TInt i = 0; i < aScheduleSlots.Count(); i++)
       
   439         {
       
   440         if (now > aScheduleSlots[i].iEndTime)
       
   441             {
       
   442             aScheduleSlots.Remove( i );
       
   443             i--;
       
   444             }
       
   445         }
       
   446 
       
   447 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::BuildScheduleSlotsL()");
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // CIptvVODScheduledDownloadActiveScheduler::GetServiceIdFromScheduledProgramL
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 TIptvServiceId CIptvVODScheduledDownloadActiveScheduler::GetServiceIdFromScheduledProgramL(
       
   455         CCseScheduledProgram& aProgram ) const
       
   456     {
       
   457     return ReadApplicationDataL( aProgram.ApplicationData() );
       
   458     }
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // CIptvVODScheduledDownloadActiveScheduler::WriteApplicationDataL
       
   462 // -----------------------------------------------------------------------------
       
   463 //
       
   464 HBufC8* CIptvVODScheduledDownloadActiveScheduler::WriteApplicationDataL() const
       
   465     {
       
   466 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::WriteApplicationDataL()");
       
   467 
       
   468     HBufC8* data = HBufC8::NewLC( sizeof(TIptvServiceId) );
       
   469     TPtr8 dataPtr( data->Des() );
       
   470 
       
   471     RDesWriteStream writeStream;
       
   472     CleanupClosePushL( writeStream );
       
   473     writeStream.Open( dataPtr );
       
   474     writeStream.WriteUint32L( iServiceId );
       
   475     CleanupStack::PopAndDestroy( &writeStream );
       
   476 
       
   477     CleanupStack::Pop( data );
       
   478 
       
   479 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::WriteApplicationDataL()");
       
   480 
       
   481     return data;
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CIptvVODScheduledDownloadActiveScheduler::ReadApplicationDataL
       
   486 // -----------------------------------------------------------------------------
       
   487 //
       
   488 TIptvServiceId CIptvVODScheduledDownloadActiveScheduler::ReadApplicationDataL(
       
   489         TPtrC8 aDataPtr ) const
       
   490     {
       
   491 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::ReadApplicationDataL()");
       
   492 
       
   493     RDesReadStream readStream;
       
   494     CleanupClosePushL( readStream );
       
   495     readStream.Open( aDataPtr );
       
   496     TIptvServiceId serviceId = readStream.ReadUint32L();
       
   497     CleanupStack::PopAndDestroy( &readStream );
       
   498 
       
   499 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::ReadApplicationDataL()");
       
   500 
       
   501     return serviceId;
       
   502     }
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // CIptvVODScheduledDownloadActiveScheduler::RandomizeRunTime
       
   506 // -----------------------------------------------------------------------------
       
   507 //
       
   508 TTime CIptvVODScheduledDownloadActiveScheduler::RandomizeRunTime(
       
   509         const TScheduleSlot& aSlot ) const
       
   510     {
       
   511 	IPTVLOGSTRING_HIGH_LEVEL(">>> CIptvVODScheduledDownloadActiveScheduler::RandomizeRunTime()");
       
   512 
       
   513     TTime start;
       
   514     start.UniversalTime();
       
   515     TBool moveStart = EFalse;
       
   516 
       
   517     //  Earliest start is either slot start or current time
       
   518     if (start < aSlot.iStartTime)
       
   519         {
       
   520         start = aSlot.iStartTime;
       
   521         moveStart = ETrue;
       
   522         }
       
   523 
       
   524     //  Get difference in minutes
       
   525     TTimeIntervalMinutes    diffMinutes;
       
   526     aSlot.iEndTime.MinutesFrom( start, diffMinutes );
       
   527 
       
   528     //  If the end time is earlier than start time, just use the start time
       
   529     if (diffMinutes.Int() < 0)
       
   530         {
       
   531     	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::RandomizeRunTime()");
       
   532         return start;
       
   533         }
       
   534 
       
   535     TInt diff = diffMinutes.Int();
       
   536 
       
   537     TTime retVal( start.Int64() );
       
   538     TInt32 tenPercent = diff / KIptvTenPercentDivider;
       
   539     TTimeIntervalMinutes tenPercentMinutes( tenPercent );
       
   540 
       
   541     //  Start time is moved 10% forward if the start time is now
       
   542     if (moveStart)
       
   543         {
       
   544         diff -= tenPercent;
       
   545         retVal += tenPercentMinutes;
       
   546         }
       
   547 
       
   548     //  Start it at least 20% before the end time
       
   549     diff -= KIptvTwiceTenPercent * tenPercent;
       
   550 
       
   551     //  Randomize the differences
       
   552     TUint32 random = Math::Random();
       
   553     TUint64 resultRandom =
       
   554             (TUint64(random) * TUint64(diff)) / TUint64(KMaxTUint32);
       
   555 
       
   556     TTimeIntervalMinutes    randomMinutes( resultRandom );
       
   557 
       
   558     //  Move random time to forward
       
   559     retVal += randomMinutes;
       
   560 
       
   561     // Note: We need to set microseconds to zero because for some reason schedule 
       
   562     // data reading from CSE database does not work correctly in E90 if microsecond
       
   563     // component is set to non-zero value.
       
   564     TDateTime fixedDate = retVal.DateTime();
       
   565     fixedDate.SetMicroSecond( 0 );
       
   566     TTime retValWithoutMicroSeconds( fixedDate );
       
   567 
       
   568 	IPTVLOGSTRING_HIGH_LEVEL("<<< CIptvVODScheduledDownloadActiveScheduler::RandomizeRunTime()");
       
   569 
       
   570     return retValWithoutMicroSeconds;
       
   571     }
       
   572 
       
   573 
       
   574 // End of File