videocollection/hgmyvideos/src/vcxhgmyvideosvideodataupdater.cpp
branchRCL_3
changeset 9 5294c000a26d
parent 8 ce5ada96ab30
child 15 8f0df5c82986
equal deleted inserted replaced
8:ce5ada96ab30 9:5294c000a26d
    39 #include "vcxhgmyvideosvideolist.h"
    39 #include "vcxhgmyvideosvideolist.h"
    40 #include "vcxhgmyvideosvideodataupdater.h"
    40 #include "vcxhgmyvideosvideodataupdater.h"
    41 #include "vcxhgmyvideosindicatorhelper.h"
    41 #include "vcxhgmyvideosindicatorhelper.h"
    42 #include "vcxhgmyvideosthumbnailmanager.h"
    42 #include "vcxhgmyvideosthumbnailmanager.h"
    43 
    43 
    44 const TInt KRefreshTimerInterval( 1000000 ); // 1 second
    44 const TInt KRefreshTimerInterval( 1000000 );    // 1 second
    45 const TInt KMaxThumbnailReqs( 2 ); // Max count of peek and get reqs combined
    45 const TInt KMaxThumbnailReqs( 2 );              // Max count of peek and get reqs combined
    46 const TInt KMaxThumbnailGetReqs( 1 ); // Max count of get reqs
    46 const TInt KMaxThumbnailGetReqs( 1 );           // Max count of get reqs
       
    47 const TInt KMaxPredictiveSelect( 10 );          // Max range for selecting items before/after visible area
       
    48 const TInt KScrollCheckInterval( 250000 );      // 0.25 seconds
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // TimeStamp
       
    52 // -----------------------------------------------------------------------------
       
    53 //
       
    54 static TInt64 TimeStamp()
       
    55     {
       
    56     TTime time;
       
    57     time.UniversalTime();
       
    58     return time.Int64();
       
    59     }
    47 
    60 
    48 // ============================ MEMBER FUNCTIONS ===============================
    61 // ============================ MEMBER FUNCTIONS ===============================
    49 
    62 
    50 // -----------------------------------------------------------------------------
    63 // -----------------------------------------------------------------------------
    51 // CVcxHgMyVideosVideoDataUpdater::NewL()
    64 // CVcxHgMyVideosVideoDataUpdater::NewL()
   104 // -----------------------------------------------------------------------------
   117 // -----------------------------------------------------------------------------
   105 //
   118 //
   106 void CVcxHgMyVideosVideoDataUpdater::ConstructL()
   119 void CVcxHgMyVideosVideoDataUpdater::ConstructL()
   107     {
   120     {
   108     iRefreshTimer = CPeriodic::NewL( CActive::EPriorityStandard );
   121     iRefreshTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   122     iRetryTimer =   CPeriodic::NewL( CActive::EPriorityStandard );
   109     iModel.ThumbnailManager().AddObserverL( *this );
   123     iModel.ThumbnailManager().AddObserverL( *this );
   110     }
   124     }
   111 
   125 
   112 // -----------------------------------------------------------------------------
   126 // -----------------------------------------------------------------------------
   113 // CVcxHgMyVideosVideoDataUpdater::InfoArrayChanged()
   127 // CVcxHgMyVideosVideoDataUpdater::InfoArrayChanged()
   128 CVcxHgMyVideosVideoDataUpdater::~CVcxHgMyVideosVideoDataUpdater()
   142 CVcxHgMyVideosVideoDataUpdater::~CVcxHgMyVideosVideoDataUpdater()
   129     {
   143     {
   130     iModel.ThumbnailManager().RemoveObserver( *this );
   144     iModel.ThumbnailManager().RemoveObserver( *this );
   131     Cancel();
   145     Cancel();
   132     delete iRefreshTimer; // Cancels active timer
   146     delete iRefreshTimer; // Cancels active timer
       
   147     delete iRetryTimer;
   133     iFetchArray.ResetAndDestroy();
   148     iFetchArray.ResetAndDestroy();
   134     }
   149     }
   135 
   150 
   136 // -----------------------------------------------------------------------------
   151 // -----------------------------------------------------------------------------
   137 // CVcxHgMyVideosVideoDataUpdater::SetPausedL()
   152 // CVcxHgMyVideosVideoDataUpdater::SetPausedL()
   179 // CVcxHgMyVideosVideoDataUpdater::ReleaseData()
   194 // CVcxHgMyVideosVideoDataUpdater::ReleaseData()
   180 // -----------------------------------------------------------------------------
   195 // -----------------------------------------------------------------------------
   181 //
   196 //
   182 void CVcxHgMyVideosVideoDataUpdater::ReleaseData( TMPXItemId aMPXItemId )
   197 void CVcxHgMyVideosVideoDataUpdater::ReleaseData( TMPXItemId aMPXItemId )
   183     {
   198     {
   184     RemoveItem( IndexByMPXItemId( aMPXItemId ) );  
   199     TInt index = IndexByMPXItemId( aMPXItemId );
       
   200     if ( index >= 0 )
       
   201         {
       
   202         RemoveItem( index ); 
       
   203         }
       
   204     }
       
   205 
       
   206 // -----------------------------------------------------------------------------
       
   207 // CVcxHgMyVideosVideoDataUpdater::PrepareForMoveOrDelete()
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 void CVcxHgMyVideosVideoDataUpdater::PrepareForMoveOrDelete( TMPXItemId aMPXItemId )
       
   211     {
       
   212     TInt index = IndexByMPXItemId( aMPXItemId );
       
   213     if ( index >= 0 )
       
   214         {
       
   215         RemoveAndCancelThumbnailGeneration( index ); 
       
   216         }
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CVcxHgMyVideosVideoDataUpdater::RemoveAndCancelThumbnailGeneration()
       
   221 // -----------------------------------------------------------------------------
       
   222 //
       
   223 void CVcxHgMyVideosVideoDataUpdater::RemoveAndCancelThumbnailGeneration( TInt aIndex )
       
   224     {
       
   225     if ( aIndex >= 0 && aIndex < iFetchArray.Count() )
       
   226         {
       
   227         // Can be enabled when cancellation of (hd) thumbnail gets faster and
       
   228         // does not hang up UI
       
   229         CancelActivities( aIndex );
       
   230         delete iFetchArray[aIndex];
       
   231         iFetchArray.Remove( aIndex );
       
   232         }
   185     }
   233     }
   186 
   234 
   187 // -----------------------------------------------------------------------------
   235 // -----------------------------------------------------------------------------
   188 // CVcxHgMyVideosVideoDataUpdater::RemoveItem()
   236 // CVcxHgMyVideosVideoDataUpdater::RemoveItem()
   189 // -----------------------------------------------------------------------------
   237 // -----------------------------------------------------------------------------
   190 //
   238 //
   191 void CVcxHgMyVideosVideoDataUpdater::RemoveItem( TInt aIndex )
   239 void CVcxHgMyVideosVideoDataUpdater::RemoveItem( TInt aIndex )
   192     {
   240     {
   193     if ( aIndex >= 0 && aIndex < iFetchArray.Count() )
   241     if ( aIndex >= 0 && aIndex < iFetchArray.Count() )
   194         {
   242         {    
   195         CancelActivities( aIndex );
   243         CVcxHgMyVideosVideoData* item = iFetchArray[aIndex];
   196         
   244         
   197         delete iFetchArray[aIndex];
   245         // When scrolling around canceling thumbnail creation is sometimes so slow
   198         iFetchArray[aIndex] = NULL;
   246         // that it hangs UI for while. Thumbnail is needed sooner or later anyway.
   199         iFetchArray.Remove( aIndex );
   247         // Therefore let creation get finished in peace. It is possible to fetch already 
   200         }    
   248         // created thumbs during creation but not during hang up. 
       
   249         if ( item && !CancelNeeded( *item ) )
       
   250             {
       
   251             delete item;
       
   252             iFetchArray.Remove( aIndex );
       
   253             }         
       
   254         }
   201     }
   255     }
   202 
   256 
   203 // -----------------------------------------------------------------------------
   257 // -----------------------------------------------------------------------------
   204 // CVcxHgMyVideosVideoDataUpdater::AddItemToFetchArrayL()
   258 // CVcxHgMyVideosVideoDataUpdater::AddItemToFetchArrayL()
   205 // -----------------------------------------------------------------------------
   259 // -----------------------------------------------------------------------------
   219 //
   273 //
   220 void CVcxHgMyVideosVideoDataUpdater::CancelActivities( TInt aIndex )
   274 void CVcxHgMyVideosVideoDataUpdater::CancelActivities( TInt aIndex )
   221     {    
   275     {    
   222     if ( aIndex >= 0 && aIndex < iFetchArray.Count() )
   276     if ( aIndex >= 0 && aIndex < iFetchArray.Count() )
   223         {
   277         {
   224 		CVcxHgMyVideosVideoData* item = iFetchArray[aIndex];
   278         CVcxHgMyVideosVideoData* item = iFetchArray[aIndex];
   225         CVcxHgMyVideosVideoData::TVideoDataState state = item->State();
   279         if ( item && CancelNeeded( *item ) )
   226         if ( state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted ||
       
   227              state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted )
       
   228             {
   280             {
   229             iModel.ThumbnailManager().Cancel( item->ThumbnailConversionId() );
   281             iModel.ThumbnailManager().Cancel( item->ThumbnailConversionId() );
   230             }
   282             }
   231         }
   283         }
   232     }
   284     }
   234 // -----------------------------------------------------------------------------
   286 // -----------------------------------------------------------------------------
   235 // CVcxHgMyVideosVideoDataUpdater::CancelAndDeleteFetchArray()
   287 // CVcxHgMyVideosVideoDataUpdater::CancelAndDeleteFetchArray()
   236 // -----------------------------------------------------------------------------
   288 // -----------------------------------------------------------------------------
   237 //
   289 //
   238 void CVcxHgMyVideosVideoDataUpdater::CancelAndDeleteFetchArray()
   290 void CVcxHgMyVideosVideoDataUpdater::CancelAndDeleteFetchArray()
   239     {    
   291     {
   240     TInt count = iFetchArray.Count();
   292     TInt count = iFetchArray.Count();
   241     for ( TInt i = 0; i < count; i++ )
   293     for ( TInt i = 0; i < count; i++ )
   242         {
   294         {
   243         CancelActivities( i );
   295         CancelActivities( i );
   244         }
   296         }
   245     iFetchArray.ResetAndDestroy();
   297     iFetchArray.ResetAndDestroy();
       
   298     
       
   299     iPreviousFirstScrollerIndexTime = 0;
       
   300     iPreviousFirstScrollerIndex = iScroller.FirstIndexOnScreen();
       
   301     iPreviousModifiedIndexOnScreen = EFalse;
   246     }
   302     }
   247 
   303 
   248 // -----------------------------------------------------------------------------
   304 // -----------------------------------------------------------------------------
   249 // CVcxHgMyVideosVideoDataUpdater::ContinueVideoDataFetchingL()
   305 // CVcxHgMyVideosVideoDataUpdater::ContinueVideoDataFetchingL()
   250 // -----------------------------------------------------------------------------
   306 // -----------------------------------------------------------------------------
   251 //
   307 //
   252 void CVcxHgMyVideosVideoDataUpdater::ContinueVideoDataFetchingL()
   308 void CVcxHgMyVideosVideoDataUpdater::ContinueVideoDataFetchingL()
   253     {
   309     {
       
   310     iRetryTimer->Cancel();
   254     if ( !iPaused && iVideoArray.VideoCount() > 0 && iFetchArray.Count() > 0 )
   311     if ( !iPaused && iVideoArray.VideoCount() > 0 && iFetchArray.Count() > 0 )
   255         {
   312         {
   256         TBool startRefreshTimer = EFalse;
   313         TInt64 time = TimeStamp();
       
   314         TBool refreshTimerNeeded = EFalse;
   257         TInt peekReqs = 0;
   315         TInt peekReqs = 0;
   258         TInt getReqs = 0;
   316         TInt getReqs = 0;
   259         GetActiveRequestCount( peekReqs, getReqs );
   317         GetActiveRequestCount( peekReqs, getReqs );
   260         TInt reqs = peekReqs + getReqs;
   318         TInt reqs = peekReqs + getReqs;
   261         if ( reqs < KMaxThumbnailReqs )
   319         if ( reqs < KMaxThumbnailReqs )
   266             CVcxHgMyVideosVideoData* item = NULL;
   324             CVcxHgMyVideosVideoData* item = NULL;
   267             do
   325             do
   268                 {
   326                 {
   269                 TInt err = KErrNone;
   327                 TInt err = KErrNone;
   270                 prevItem = item;
   328                 prevItem = item;
   271                 SelectNextIndexL( getReqs >= KMaxThumbnailGetReqs );
   329                 if ( !SelectNextIndexL( getReqs >= KMaxThumbnailGetReqs ) )
       
   330                     {
       
   331                     // Nothing to be started
       
   332                     if ( !reqs && iFetchArray.Count() > 0 )
       
   333                         {
       
   334                         // To ensure that thumbnail creation continues after
       
   335                         // disabled while scrolling
       
   336                         iRetryTimer->Start( KScrollCheckInterval, KScrollCheckInterval,
       
   337                             TCallBack( RetryTimerCallBack, this ) );
       
   338                         iPreviousFirstScrollerIndexTime = 0; // Force scroll check update
       
   339                         IPTVLOGSTRING_LOW_LEVEL(
       
   340                            "MPX My Videos UI # ContinueVideoDataFetchingL # iRetryTimer start" );
       
   341                         }
       
   342                     break;
       
   343                     }
   272                 item = iFetchArray[0];
   344                 item = iFetchArray[0];
   273                 state = item->State();
   345                 state = item->State();
   274                 if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone )
   346                 if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone )
   275                     {
   347                     {
   276                     // Try first a quick peek with thumbnail creation denied
   348                     // Try first a quick peek with thumbnail creation denied
   277                     TRAP( err, StartThumbnailL( *item, ETrue ) );
   349                     TRAP( err, StartThumbnailL( *item, ETrue ) );
   278                     if( err == KErrNone )
   350                     if( err == KErrNone )
   279                         {
   351                         {
   280                         ++reqs;
   352                         ++reqs;
   281                         startRefreshTimer = ETrue;
   353                         refreshTimerNeeded = ETrue;
   282                         }
   354                         }
   283                     }
   355                     }
   284                 else if ( state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekFinished ) 
   356                 else if ( state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekFinished ) 
   285                     {
   357                     {
   286                     if ( getReqs < KMaxThumbnailGetReqs )
   358                     if ( getReqs < KMaxThumbnailGetReqs )
   289                         TRAP( err, StartThumbnailL( *item, EFalse ) );
   361                         TRAP( err, StartThumbnailL( *item, EFalse ) );
   290                         if ( err == KErrNone )
   362                         if ( err == KErrNone )
   291                             {
   363                             {
   292                             ++reqs;
   364                             ++reqs;
   293                             ++getReqs;
   365                             ++getReqs;
   294                             startRefreshTimer = ETrue;
   366                             refreshTimerNeeded = ETrue;
   295                             }
   367                             }
   296                         }
   368                         }
   297                     }
   369                     }
   298                 else
       
   299                     {
       
   300                     break; // Nothing to be started
       
   301                     }
       
   302                 if ( err != KErrNone )
   370                 if ( err != KErrNone )
   303                     {
   371                     {
   304                     RemoveItem( 0 );
   372                     RemoveItem( 0 );
   305                     }                
   373                     }                
   306                 }
   374                 }
   307             while ( iFetchArray.Count() > 0 && reqs < KMaxThumbnailReqs && prevItem != item );
   375             while ( iFetchArray.Count() > 0 && reqs < KMaxThumbnailReqs && prevItem != item );
   308             }
   376             }
   309         if ( startRefreshTimer )
   377         if ( refreshTimerNeeded && !iRefreshTimer->IsActive() )
   310             {
   378             {
   311             iRefreshTimer->Cancel();
       
   312             iRefreshTimer->Start( KRefreshTimerInterval, KRefreshTimerInterval,
   379             iRefreshTimer->Start( KRefreshTimerInterval, KRefreshTimerInterval,
   313                 TCallBack( RefreshTimerCallBack, this ) );
   380                 TCallBack( RefreshTimerCallBack, this ) );
       
   381             IPTVLOGSTRING_LOW_LEVEL(
       
   382                "MPX My Videos UI # ContinueVideoDataFetchingL # iRefreshTimer start" );
       
   383             }
       
   384         if ( time - iPreviousFirstScrollerIndexTime >= KScrollCheckInterval )
       
   385             {
       
   386             // Store values for scroll direction check
       
   387             iPreviousFirstScrollerIndexTime = time;
       
   388             iPreviousFirstScrollerIndex = iScroller.FirstIndexOnScreen();
   314             }
   389             }
   315         }
   390         }
   316     }
   391     }
   317 
   392 
   318 // -----------------------------------------------------------------------------
   393 // -----------------------------------------------------------------------------
   410 
   485 
   411 // -----------------------------------------------------------------------------
   486 // -----------------------------------------------------------------------------
   412 // CVcxHgMyVideosVideoDataUpdater::SelectNextIndexL()
   487 // CVcxHgMyVideosVideoDataUpdater::SelectNextIndexL()
   413 // -----------------------------------------------------------------------------
   488 // -----------------------------------------------------------------------------
   414 // 
   489 // 
   415 void CVcxHgMyVideosVideoDataUpdater::SelectNextIndexL( TBool aSelectForPeekOnly )
   490 TBool CVcxHgMyVideosVideoDataUpdater::SelectNextIndexL( TBool aSelectForPeekOnly )
   416     {   
   491     {
   417     TInt firstIndexOnScreen = iScroller.FirstIndexOnScreen();
   492     TBool selected = EFalse;
   418     
   493     if ( iScroller.ItemCount() > 0 )
   419     if ( firstIndexOnScreen < 0 ) 
   494         {
   420         {
   495         TInt firstIndexOnScreen = 0;
   421         firstIndexOnScreen = 0;
   496         TInt lastIndexOnScreen = 0;
   422         }
   497         TInt lastIndex = 0;
   423     
   498         GetScrollerArea( firstIndexOnScreen, lastIndexOnScreen, lastIndex );
   424     TInt lastIndexOnScreen = firstIndexOnScreen + iScroller.ItemsOnScreen();
   499 
   425    
   500         // Determine scroll direction for optimal selection
   426     if ( lastIndexOnScreen >= iScroller.ItemCount() )
   501         TInt maxPredict = KMaxPredictiveSelect;
   427         {
   502         TBool scrollUp = iPreviousFirstScrollerIndex > firstIndexOnScreen;
   428         lastIndexOnScreen = iScroller.ItemCount() - 1;
   503         TBool scrollDown = iPreviousFirstScrollerIndex < firstIndexOnScreen;
   429         }
   504         if ( scrollUp || scrollDown )
   430          
   505             {
   431     // If visible items not found, updater takes object from 0 index. 
   506             if ( scrollUp )
   432     for ( TInt i = firstIndexOnScreen; i <= lastIndexOnScreen; i++ )
   507                 {
   433         {      
   508                 IPTVLOGSTRING_LOW_LEVEL(
   434         TInt index( KErrNotFound );
   509                    "MPX My Videos UI # CVcxHgMyVideosVideoDataUpdater # scroll up" );
   435         TMPXItemId mpxItemId;
   510                 }
   436         CGulIcon* icon( NULL );
   511             else
   437         
   512                 {
   438         // Skip if list item already have a thumbnail.
   513                 IPTVLOGSTRING_LOW_LEVEL(
   439         icon = iScroller.ItemL( i ).Icon();
   514                     "MPX My Videos UI # CVcxHgMyVideosVideoDataUpdater # scroll down" );
   440         if ( !icon )
   515                 }
   441             {
   516             aSelectForPeekOnly = ETrue; // Disable thumb creation while scrolling
   442             mpxItemId = iVideoArray.ArrayIndexToMpxItemIdL( i );
   517             }
   443             index = IndexByMPXItemId( mpxItemId );
   518         else
   444 
   519             {
   445             if ( index >= 0 )
   520             maxPredict /= 2; // Split range when checking both directions
   446                 {
   521             }
   447                 CVcxHgMyVideosVideoData* item = iFetchArray[index];
   522 
   448                 CVcxHgMyVideosVideoData::TVideoDataState state = item->State();
   523         if ( !aSelectForPeekOnly || scrollUp )
   449                 // Move selected index to first index of the fetch array. 
   524             {
   450                 if ( aSelectForPeekOnly )
   525             // Try visible area first with thumb creation disabled to get
   451                     {
   526             // already created thumbs as fast as possible
   452                     if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone )
   527             selected = TrySelectFromScrollerAreaL( firstIndexOnScreen, 
   453                         {
   528                                                    lastIndexOnScreen,
   454                         iFetchArray.InsertL( item, 0 );
   529                                                    ETrue );
   455                         iFetchArray.Remove( index + 1 );
   530             }
   456                         break;
   531         if ( !selected && !scrollUp )
   457                         }
   532             {
   458                     }
   533             // Try visible area and items below
   459                 else if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone ||
   534             TInt end = Min( lastIndexOnScreen + maxPredict, lastIndex );
   460                           state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekFinished )
   535             selected = TrySelectFromScrollerAreaL( firstIndexOnScreen, end, 
   461                     {
   536                     aSelectForPeekOnly );
   462                     iFetchArray.InsertL( item, 0 );
   537             }
   463                     iFetchArray.Remove( index + 1 );
   538         if ( !selected && !scrollDown && firstIndexOnScreen > 0 )
       
   539             {
       
   540             // Try items above visible area
       
   541             TInt end = Max( firstIndexOnScreen - maxPredict - 1, 0 );
       
   542             selected = TrySelectFromScrollerAreaL( firstIndexOnScreen - 1, end,
       
   543                     aSelectForPeekOnly );
       
   544             }
       
   545         if ( !selected )
       
   546             {
       
   547             // Try any item
       
   548             TInt count = iFetchArray.Count();
       
   549             for ( TInt i = 0; i < count; i++ )
       
   550                 {
       
   551                 if ( TrySelectL( i, aSelectForPeekOnly ) )
       
   552                     {
       
   553                     selected = ETrue;
   464                     break;
   554                     break;
   465                     }
   555                     }
   466                 }
   556                 }
   467             }
   557             }
   468         }
   558         }
       
   559     return selected;
   469     }
   560     }
   470 
   561 
   471 // -----------------------------------------------------------------------------
   562 // -----------------------------------------------------------------------------
   472 // CVcxHgMyVideosVideoDataUpdater::RefreshTimerCallBack()
   563 // CVcxHgMyVideosVideoDataUpdater::RefreshTimerCallBack()
   473 // -----------------------------------------------------------------------------
   564 // -----------------------------------------------------------------------------
   474 //
   565 //
   475 TInt CVcxHgMyVideosVideoDataUpdater::RefreshTimerCallBack( TAny* aAny )
   566 TInt CVcxHgMyVideosVideoDataUpdater::RefreshTimerCallBack( TAny* aAny )
   476     {
   567     {
   477     CVcxHgMyVideosVideoDataUpdater* self = static_cast<CVcxHgMyVideosVideoDataUpdater*>( aAny ); 
   568     CVcxHgMyVideosVideoDataUpdater* self = static_cast<CVcxHgMyVideosVideoDataUpdater*>( aAny ); 
   478     self->iRefreshTimer->Cancel();
   569     if ( !self->iPaused && self->iFetchArray.Count() > 0 )
   479     if ( self->iListRefreshIsDelayed )
   570         {
   480         {
   571         // Do refresh only if on screen item has been modified
   481         self->iListRefreshIsDelayed = EFalse;
   572         if ( self->iPreviousModifiedIndexOnScreen )
   482         if ( !self->iPaused )
   573             {
   483             {
   574             self->iPreviousModifiedIndexOnScreen = EFalse; // Reset refresh checking
   484             self->RefreshScreen();
   575             self->RefreshScreen();
   485             }
   576             }
       
   577         }
       
   578     else
       
   579         {
       
   580         self->iRefreshTimer->Cancel();
       
   581         IPTVLOGSTRING_LOW_LEVEL(
       
   582            "MPX My Videos UI # RefreshTimerCallBack # iRefreshTimer stop" );
   486         }
   583         }
   487     return KErrNone;
   584     return KErrNone;
   488     }
   585     }
   489 
   586 
   490 // -----------------------------------------------------------------------------
   587 // -----------------------------------------------------------------------------
   501 // CVcxHgMyVideosVideoDataUpdater::ListRefreshNeeded()
   598 // CVcxHgMyVideosVideoDataUpdater::ListRefreshNeeded()
   502 // -----------------------------------------------------------------------------
   599 // -----------------------------------------------------------------------------
   503 //
   600 //
   504 TBool CVcxHgMyVideosVideoDataUpdater::ListRefreshNeeded( TInt aIndex )
   601 TBool CVcxHgMyVideosVideoDataUpdater::ListRefreshNeeded( TInt aIndex )
   505     {
   602     {
   506     TBool modifiedIndexOnScreen( EFalse );
   603     TInt firstIndexOnScreen = 0;
   507     TInt firstIndexOnScreen( iScroller.FirstIndexOnScreen() );
   604     TInt lastIndexOnScreen = 0;
       
   605     TInt lastIndex = 0;
       
   606     GetScrollerArea( firstIndexOnScreen, lastIndexOnScreen, lastIndex );
   508     
   607     
   509     if ( firstIndexOnScreen < 0 )
   608     TBool modifiedIndexOnScreen = aIndex >= firstIndexOnScreen &&
   510         {
   609         aIndex <= lastIndexOnScreen;
   511         firstIndexOnScreen = 0;
       
   512         }
       
   513     
       
   514     TInt lastIndexOnScreen = firstIndexOnScreen + iScroller.ItemsOnScreen(); 
       
   515     
       
   516     if ( lastIndexOnScreen >= iScroller.ItemCount() )
       
   517         {
       
   518         lastIndexOnScreen = iScroller.ItemCount() - 1;
       
   519         }
       
   520          
       
   521     if ( aIndex >= firstIndexOnScreen && aIndex <= lastIndexOnScreen )
       
   522         {
       
   523         modifiedIndexOnScreen = ETrue;
       
   524         }
       
   525     
       
   526     TBool timerHasExpired( ! iRefreshTimer->IsActive() );
       
   527     TBool refreshNeeded( EFalse );
   610     TBool refreshNeeded( EFalse );
   528     
   611 
   529     if ( ( iListRefreshIsDelayed && !modifiedIndexOnScreen ) 
   612     // Refresh rules:
   530             || iFetchArray.Count() <= 1 || timerHasExpired )
   613     // 1) Refresh if off screen item is detected after on screen item
   531         {
   614     // 2) Refresh if item is the last
   532         iListRefreshIsDelayed = EFalse;
   615     if ( ( iPreviousModifiedIndexOnScreen && !modifiedIndexOnScreen ) ||
   533         refreshNeeded = ETrue;        
   616          iFetchArray.Count() <= 1 )
   534         }        
   617         {
   535     else if ( modifiedIndexOnScreen )
   618         // Restart refresh timer if there are items left after current one
   536         {
   619         iRefreshTimer->Cancel();
   537         iListRefreshIsDelayed = ETrue;    
   620         if ( iFetchArray.Count() > 1 )
   538         }
   621             {
   539     
   622             iRefreshTimer->Start( KRefreshTimerInterval, KRefreshTimerInterval,
       
   623                 TCallBack( RefreshTimerCallBack, this ) );
       
   624             IPTVLOGSTRING_LOW_LEVEL(
       
   625                "MPX My Videos UI # ListRefreshNeeded # iRefreshTimer start" );
       
   626             }
       
   627         else
       
   628             {
       
   629             IPTVLOGSTRING_LOW_LEVEL(
       
   630                "MPX My Videos UI # ListRefreshNeeded # iRefreshTimer stop" );
       
   631             }
       
   632         refreshNeeded = ETrue;
       
   633         }
       
   634     iPreviousModifiedIndexOnScreen = modifiedIndexOnScreen;
   540     return refreshNeeded;
   635     return refreshNeeded;
   541     }
   636     }
   542 
   637 
   543 // -----------------------------------------------------------------------------
   638 // -----------------------------------------------------------------------------
   544 // CVcxHgMyVideosVideoDataUpdater::ThumbnailPreviewReady()
   639 // CVcxHgMyVideosVideoDataUpdater::ThumbnailPreviewReady()
   573                  item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted )
   668                  item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted )
   574                 {
   669                 {
   575                 // Never delete this, ownership gone to Ganes list
   670                 // Never delete this, ownership gone to Ganes list
   576                 item->SetThumbnail( aError == KErrNone ? aThumbnail.DetachBitmap() : NULL );
   671                 item->SetThumbnail( aError == KErrNone ? aThumbnail.DetachBitmap() : NULL );
   577                 item->SetState( CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished );
   672                 item->SetState( CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished );
       
   673                 StartFinalActions();
   578                 }
   674                 }
   579             else if ( aError == KErrNotFound &&
   675             else if ( aError == KErrNotFound &&
   580             	item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted )
   676             	item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted )
   581                 {
   677                 {
   582                 // Try getting thumbnail with create allowed when peek failed with not found
   678                 // Try getting thumbnail with create allowed when peek failed with not found
   584                 }
   680                 }
   585             else
   681             else
   586                 {
   682                 {
   587                 // Stop thumbnail peek attemps
   683                 // Stop thumbnail peek attemps
   588                 item->SetState( CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished );
   684                 item->SetState( CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished );
   589                 }
   685                 StartFinalActions();
   590 
       
   591 			// Start DRM check if thumb finished
       
   592             if ( item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished && 
       
   593 			     !IsActive() )
       
   594                 {
       
   595                 SetActive();
       
   596                 TRequestStatus* stat = &iStatus;
       
   597                 User::RequestComplete( stat, KErrNone );
       
   598                 }
   686                 }
   599 
   687 
   600             TRAPD( err, ContinueVideoDataFetchingL() );
   688             TRAPD( err, ContinueVideoDataFetchingL() );
   601             if ( err != KErrNone )
   689             if ( err != KErrNone )
   602                 {
   690                 {
   616 //
   704 //
   617 void CVcxHgMyVideosVideoDataUpdater::RunL()
   705 void CVcxHgMyVideosVideoDataUpdater::RunL()
   618     {
   706     {
   619     if ( !iPaused )
   707     if ( !iPaused )
   620         {
   708         {
   621         TInt i = 0;
   709         TInt i = iFetchArray.Count() - 1;
   622         while( i < iFetchArray.Count() )
   710         while( i >= 0 )
   623             {
   711             {
   624             CVcxHgMyVideosVideoData* item = iFetchArray[i];
   712             CVcxHgMyVideosVideoData* item = iFetchArray[i];
   625             if ( item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished )
   713             if ( item->State() == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished )
   626                 {
   714                 {
   627                 TRAP_IGNORE(
   715                 TRAP_IGNORE(
   628                     {
   716                     {
   629                     CheckDrmL( *item );
   717                     CheckDrmL( *item );
   630                     UpdateVideoDataToUiL( *item );
   718                     UpdateVideoDataToUiL( *item );
   631                     } );
   719                     } );				
   632                 delete iFetchArray[i];
   720                 delete item;
   633                 iFetchArray.Remove(i);
   721                 iFetchArray.Remove(i);
   634                 }
   722 #if 0
   635             else
   723                 if ( iFetchArray.Count() > 0 )
   636                 {
   724                     {
   637                 ++i;
   725                     // If drm checking is time consuming, proceed finalisation later
   638                 }
   726                     StartFinalActions();
   639             }
   727                     break;
   640         ContinueVideoDataFetchingL();
   728                     }
       
   729 #endif
       
   730                 }
       
   731             --i;
       
   732             }
       
   733         if ( !iFetchArray.Count() )
       
   734             {
       
   735             // No items left, timers are not needed anymore
       
   736             iRefreshTimer->Cancel();
       
   737             iRetryTimer->Cancel();
       
   738             IPTVLOGSTRING_LOW_LEVEL(
       
   739                "MPX My Videos UI # RunL # iRefreshTimer stop" );
       
   740             }
   641         }
   741         }
   642     }
   742     }
   643 
   743 
   644 // -----------------------------------------------------------------------------
   744 // -----------------------------------------------------------------------------
   645 // CVcxHgMyVideosVideoDataUpdater::RunError()
   745 // CVcxHgMyVideosVideoDataUpdater::RunError()
   760             CleanupStack::PopAndDestroy( source ); 
   860             CleanupStack::PopAndDestroy( source ); 
   761             CleanupStack::PopAndDestroy( &file );
   861             CleanupStack::PopAndDestroy( &file );
   762             }
   862             }
   763         aItem.SetThumbnailConversionId( id );
   863         aItem.SetThumbnailConversionId( id );
   764 
   864 
   765         IPTVLOGSTRING3_LOW_LEVEL( 
   865         IPTVLOGSTRING4_LOW_LEVEL( 
   766                 "MPX My Videos UI # GetThumbnailL() called thumbID %d for %S.",
   866                 "MPX My Videos UI # StartThumbnailL() called thumbID %d for %S (peek %d)",
   767                 aItem.ThumbnailConversionId(),
   867                 aItem.ThumbnailConversionId(),
   768                 &media->ValueText( KMPXMediaGeneralUri ) );
   868                 &media->ValueText( KMPXMediaGeneralUri ),
       
   869                 aPeek );
   769 
   870 
   770         aItem.SetState( aPeek ?
   871         aItem.SetState( aPeek ?
   771                 CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted :
   872                 CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted :
   772                 CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted );
   873                 CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted );
   773         }
   874         }
   774     else
   875     else
   775         {
   876         {
   776         User::Leave( KErrNotFound );
   877         User::Leave( KErrNotFound );
   777         }
   878         }
   778     }
   879     }
       
   880 
       
   881 // -----------------------------------------------------------------------------
       
   882 // CVcxHgMyVideosVideoDataUpdater::TrySelectL()
       
   883 // -----------------------------------------------------------------------------
       
   884 //
       
   885 TBool CVcxHgMyVideosVideoDataUpdater::TrySelectL( TInt aIndex, 
       
   886                                                   TBool aSelectForPeekOnly )
       
   887     {
       
   888     // Move selected index to first index of the fetch array
       
   889     TBool selected = EFalse;
       
   890     CVcxHgMyVideosVideoData* item = iFetchArray[aIndex];
       
   891     CVcxHgMyVideosVideoData::TVideoDataState state = item->State();
       
   892     if ( aSelectForPeekOnly )
       
   893         {
       
   894         // Accept item only for peeking
       
   895         if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone )
       
   896             {
       
   897             iFetchArray.InsertL( item, 0 );
       
   898             iFetchArray.Remove( aIndex + 1 );
       
   899             selected = ETrue;
       
   900             }
       
   901         }
       
   902     else if ( state == CVcxHgMyVideosVideoData::EVideoDataStateNone ||
       
   903               state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekFinished )
       
   904         {
       
   905         // Accept any item that waits to be fetched
       
   906         iFetchArray.InsertL( item, 0 );
       
   907         iFetchArray.Remove( aIndex + 1 );
       
   908         selected = ETrue;
       
   909         }
       
   910     return selected;
       
   911     }
       
   912 
       
   913 // -----------------------------------------------------------------------------
       
   914 // CVcxHgMyVideosVideoDataUpdater::TrySelectFromScrollerL()
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 TBool CVcxHgMyVideosVideoDataUpdater::TrySelectFromScrollerL(
       
   918     TInt aPos, TBool aSelectForPeekOnly )
       
   919     {
       
   920     TBool selected = EFalse;
       
   921     CGulIcon* icon = iScroller.ItemL( aPos ).Icon();
       
   922     TMPXItemId mpxItemId = iVideoArray.ArrayIndexToMpxItemIdL( aPos );
       
   923     TInt index = IndexByMPXItemId( mpxItemId );
       
   924     if ( index >= 0 )
       
   925         {
       
   926 		// Skip fetch selection if icon already exist
       
   927         if ( !icon )
       
   928             {
       
   929             if ( TrySelectL( index, aSelectForPeekOnly ) )
       
   930                 {
       
   931                 selected = ETrue;
       
   932                 }
       
   933             }
       
   934         else
       
   935             {
       
   936             iFetchArray[index]->SetState(
       
   937                 CVcxHgMyVideosVideoData::EVideoDataStateThumbnailFinished );
       
   938             StartFinalActions();
       
   939             }
       
   940         }
       
   941     return selected;
       
   942     }
       
   943 
       
   944 // -----------------------------------------------------------------------------
       
   945 // CVcxHgMyVideosVideoDataUpdater::TrySelectFromScrollerAreaL()
       
   946 // -----------------------------------------------------------------------------
       
   947 //
       
   948 TBool CVcxHgMyVideosVideoDataUpdater::TrySelectFromScrollerAreaL( 
       
   949     TInt aStartPos, TInt aEndPos, TBool aSelectForPeekOnly )
       
   950     {
       
   951     TBool selected = EFalse;
       
   952     if ( aEndPos >= aStartPos )
       
   953         {
       
   954         // Search forwards
       
   955         for ( TInt i = aStartPos; i <= aEndPos; i++ )
       
   956             {
       
   957             if ( TrySelectFromScrollerL( i, aSelectForPeekOnly ) )
       
   958                 {
       
   959                 selected = ETrue;
       
   960                 break;
       
   961                 }
       
   962             }
       
   963         }
       
   964     else
       
   965         {
       
   966         // Search backwards
       
   967         for ( TInt i = aStartPos; i >= aEndPos; i-- )
       
   968             {
       
   969             if ( TrySelectFromScrollerL( i, aSelectForPeekOnly ) )
       
   970                 {
       
   971                 selected = ETrue;
       
   972                 break;
       
   973                 }
       
   974             }
       
   975         }
       
   976     return selected;
       
   977     }
       
   978 
       
   979 // -----------------------------------------------------------------------------
       
   980 // CVcxHgMyVideosVideoDataUpdater::StartFinalActions()
       
   981 // -----------------------------------------------------------------------------
       
   982 //
       
   983 void CVcxHgMyVideosVideoDataUpdater::StartFinalActions()
       
   984     {
       
   985     if ( !IsActive() )
       
   986         {
       
   987         SetActive();
       
   988         TRequestStatus* stat = &iStatus;
       
   989         User::RequestComplete( stat, KErrNone );
       
   990         }
       
   991     }
       
   992 
       
   993 // -----------------------------------------------------------------------------
       
   994 // CVcxHgMyVideosVideoDataUpdater::CancelNeeded()
       
   995 // -----------------------------------------------------------------------------
       
   996 //
       
   997 TBool CVcxHgMyVideosVideoDataUpdater::CancelNeeded( CVcxHgMyVideosVideoData& aItem )
       
   998     {
       
   999     CVcxHgMyVideosVideoData::TVideoDataState state = aItem.State();
       
  1000     return ( state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailPeekStarted ||
       
  1001              state == CVcxHgMyVideosVideoData::EVideoDataStateThumbnailStarted );
       
  1002     }
       
  1003 
       
  1004 // -----------------------------------------------------------------------------
       
  1005 // CVcxHgMyVideosVideoDataUpdater::RetryTimerCallBack()
       
  1006 // -----------------------------------------------------------------------------
       
  1007 //
       
  1008 TInt CVcxHgMyVideosVideoDataUpdater::RetryTimerCallBack( TAny* aAny )
       
  1009     {
       
  1010     CVcxHgMyVideosVideoDataUpdater* self = static_cast<CVcxHgMyVideosVideoDataUpdater*>( aAny ); 
       
  1011     self->iRetryTimer->Cancel();
       
  1012     TRAPD( err, self->ContinueVideoDataFetchingL() );
       
  1013     if ( err != KErrNone )
       
  1014         {
       
  1015         IPTVLOGSTRING2_LOW_LEVEL(
       
  1016         "MPX My Videos UI # CVcxHgMyVideosVideoDataUpdater::RetryTimerCallBack, err = %d",
       
  1017         err );
       
  1018         }
       
  1019     return KErrNone;
       
  1020     }
       
  1021 
       
  1022 // -----------------------------------------------------------------------------
       
  1023 // CVcxHgMyVideosVideoDataUpdater::GetScrollerArea()
       
  1024 // -----------------------------------------------------------------------------
       
  1025 //
       
  1026 void CVcxHgMyVideosVideoDataUpdater::GetScrollerArea( TInt& aFirstIndexOnScreen, 
       
  1027                                                       TInt& aLastIndexOnScreen, 
       
  1028                                                       TInt& aLastIndex )
       
  1029     {
       
  1030     aLastIndex = Max( iScroller.ItemCount() - 1, 0 );
       
  1031     aFirstIndexOnScreen = Max( iScroller.FirstIndexOnScreen(), 0 );
       
  1032     aLastIndexOnScreen = Min( aFirstIndexOnScreen + iScroller.ItemsOnScreen(), aLastIndex );
       
  1033     }