camerauis/cameraapp/generic/src/CamSelfTimer.cpp
branchRCL_3
changeset 24 bac7acad7cb3
equal deleted inserted replaced
23:61bc0f252b2b 24:bac7acad7cb3
       
     1 /*
       
     2 * Copyright (c) 2007-2008 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 "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:  Provides the flashing icon/LED & timing capability of the*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32base.h>
       
    21 #include <e32std.h>
       
    22 #include <eikbtgpc.h>
       
    23 #include <cameraapp.rsg>
       
    24 #include <vgacamsettings.rsg>
       
    25 #include "CamSelfTimer.h"
       
    26 #include "CamPanic.h"
       
    27 #include "CamAppUi.h"
       
    28 #include "CamUtility.h"
       
    29 #include "Cam.hrh"  // For ECamSelfTimerSoundId def
       
    30 #include "OstTraceDefinitions.h"
       
    31 #ifdef OST_TRACE_COMPILER_IN_USE
       
    32 #include "CamSelfTimerTraces.h"
       
    33 #endif
       
    34 
       
    35 // CONSTANTS
       
    36 
       
    37 
       
    38 // MACROS
       
    39 
       
    40 // LOCAL CONSTANTS AND MACROS
       
    41 
       
    42 // MODULE DATA STRUCTURES
       
    43 
       
    44 // LOCAL FUNCTION PROTOTYPES
       
    45 
       
    46 // FORWARD DECLARATIONS
       
    47 
       
    48 // ============================= LOCAL FUNCTIONS ===============================
       
    49 
       
    50 
       
    51 
       
    52 
       
    53 // ============================ MEMBER FUNCTIONS ===============================
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CCamSelfTimer::NewL
       
    57 // Two-phased constructor.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 CCamSelfTimer* CCamSelfTimer::NewL( CCamAppController& aController )
       
    61     {
       
    62     CCamSelfTimer* self = new( ELeave ) CCamSelfTimer( aController );
       
    63     CleanupStack::PushL( self );
       
    64     self->ConstructL();
       
    65     CleanupStack::Pop( self );
       
    66     return self;
       
    67     }
       
    68 
       
    69     
       
    70 // Destructor
       
    71 CCamSelfTimer::~CCamSelfTimer()
       
    72   {
       
    73   PRINT( _L("Camera => ~CCamSelfTimer") );
       
    74   // If self-timer is active, stop it
       
    75   if ( IsActive() )
       
    76       {
       
    77       Cancel();
       
    78       }
       
    79 
       
    80   // close up observers array
       
    81   iObservers.Close();
       
    82 
       
    83   delete iPeriodicTimer;    
       
    84   PRINT( _L("Camera <= ~CCamSelfTimer") );
       
    85   }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CCamSelfTimer::StartSelfTimer
       
    89 // Will be called to start self timer.  If self timer is already running, the 
       
    90 // timer is cancelled and the capture operation is run immediately.
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 void CCamSelfTimer::StartSelfTimer()
       
    94   {
       
    95   // Check it is not already running
       
    96   if ( ECamSelfTimerStandby == iState )
       
    97     {
       
    98     ChangeState( ECamSelfTimerActive1 );
       
    99     }
       
   100   // If the timer is already running, then we must cancel the timer
       
   101   // and do the capture operation now!
       
   102   else  
       
   103     { 
       
   104     // Cancel the timer
       
   105     Cancel();
       
   106 
       
   107     if( ECamControllerImage == iMode )
       
   108       {
       
   109       switch ( iImageMode )
       
   110         {
       
   111         case ECamImageCaptureBurst:
       
   112         case ECamImageCaptureTimeLapse:
       
   113           {
       
   114           // Start the autofocus operation now, the capture will be queued
       
   115           // after focus completes
       
   116           OstTrace0( CAMERAAPP_PERFORMANCE, DUP7_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_APP_AF 1" );
       
   117           iController.StartAutoFocus();
       
   118           // Softkeys are blank/cancel if doing burst capture
       
   119           // but cancel means cancel ongoing burst, not cancel self-timer
       
   120           // replace the buttons with the correct command set
       
   121           CCamAppUi* appUi = static_cast<CCamAppUi*>( CEikonEnv::Static()->AppUi() );
       
   122           if ( appUi )
       
   123             {
       
   124             // blank the softkeys in preparation for capture
       
   125             TRAP_IGNORE( appUi->SetSoftKeysL( R_CAM_SOFTKEYS_BLANK_STOP ) );
       
   126             }
       
   127           }
       
   128           //lint -fallthrough
       
   129         case ECamImageCaptureSingle: 
       
   130           {
       
   131           // If still Self-Timer is interrupted, take the photo NOW.
       
   132           // If we were in multi-shot, this capture is queued
       
   133           OstTrace0( CAMERAAPP_PERFORMANCE, CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_APP_SHOT_TO_SNAPSHOT 1" );
       
   134           OstTrace0( CAMERAAPP_PERFORMANCE, DUP1_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_PRI_SHOT_TO_SNAPSHOT 1" );
       
   135           OstTrace0( CAMERAAPP_PERFORMANCE, DUP2_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_PRI_SHOT_TO_SAVE 1" );
       
   136           OstTrace0( CAMERAAPP_PERFORMANCE, DUP3_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_PRI_SHOT_TO_SHOT 1" );
       
   137           OstTrace0( CAMERAAPP_PERFORMANCE, DUP4_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_APP_SHOT_TO_STILL 1" );
       
   138           OstTrace0( CAMERAAPP_PERFORMANCE, DUP5_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_APP_CAPTURE_START 1" );
       
   139           OstTrace0( CAMERAAPP_PERFORMANCE, DUP6_CCAMSELFTIMER_STARTSELFTIMER, "e_CAM_PRI_SERIAL_SHOOTING 1" );
       
   140 
       
   141           iController.Capture();
       
   142           break;
       
   143           }
       
   144         default:
       
   145           break;
       
   146         }
       
   147       }
       
   148     else
       
   149       {
       
   150       // Start recording now
       
   151       TRAP_IGNORE( iController.StartVideoRecordingL() );
       
   152       }
       
   153     }
       
   154   }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CCamSelfTimer::SetModeL
       
   158 // Called when the current capture method (Video or Still) changes.
       
   159 // Updates the internal state (so correct capture method is called when self
       
   160 // timer expires) and if timer is already running, cancels the outstanding
       
   161 // timer (as the view has changed).
       
   162 // -----------------------------------------------------------------------------
       
   163 //
       
   164 void CCamSelfTimer::SetModeL( TCamCameraMode         aMode, 
       
   165                              TCamImageCaptureMode   aImageMode,
       
   166                              TCamSelfTimerFunctions aFunc )
       
   167   {
       
   168   iMode      = aMode;
       
   169   iImageMode = aImageMode;
       
   170   
       
   171   // Based on the supplied selftimer function (specifying periods) load the 
       
   172   // individual data from PSI.
       
   173   TPckgBuf <TSelfTimerSetting> pckg;
       
   174   
       
   175   TInt ret = KErrNone;
       
   176   switch ( aFunc )
       
   177     {
       
   178     case ECamSelfTimerMode1:
       
   179       ret = CamUtility::GetPsiAnyL( ECamPsiSelfTimerPeriod1, &pckg );
       
   180       break;
       
   181     case ECamSelfTimerMode2:
       
   182       ret = CamUtility::GetPsiAnyL( ECamPsiSelfTimerPeriod2, &pckg );
       
   183       break;
       
   184     case ECamSelfTimerMode3:
       
   185       ret = CamUtility::GetPsiAnyL( ECamPsiSelfTimerPeriod3, &pckg );
       
   186       break;            
       
   187     case ECamSelfTimerDisabled:
       
   188       //Fall-through
       
   189     default:
       
   190       break;
       
   191     }
       
   192   // Check it is supported.  
       
   193   __ASSERT_ALWAYS( ret == KErrNone, CamPanic( ECamPanicUnhandledCommand ) );
       
   194 
       
   195   iSettings = pckg();
       
   196   // Set time remaining and update observers.
       
   197   iTimeRemaining = iSettings.iThreshold[ECamSelfTimerMode1];    
       
   198   NotifyObservers( ECamSelfTimerEventTimerOn );
       
   199   }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // CCamSelfTimer::Cancel
       
   203 // Cancels the timer if already running, and returns the self timer to 
       
   204 // self-timer standby state.
       
   205 // -----------------------------------------------------------------------------
       
   206 //
       
   207 void CCamSelfTimer::Cancel()
       
   208     {
       
   209     ChangeState( ECamSelfTimerStandby );
       
   210     }
       
   211 
       
   212 // -----------------------------------------------------------------------------
       
   213 // CCamSelfTimer::IsActive
       
   214 // Returns whether or not the SelfTimer is currently active (counting down)
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 TBool CCamSelfTimer::IsActive()
       
   218     {
       
   219     if ( iState == ECamSelfTimerStandby )
       
   220         {
       
   221         return EFalse;
       
   222         }
       
   223     else
       
   224         {
       
   225         return ETrue;        
       
   226         }           
       
   227     }
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // CCamSelfTimer::CCamSelfTimer
       
   231 // C++ default constructor can NOT contain any code, that
       
   232 // might leave.
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 CCamSelfTimer::CCamSelfTimer( CCamAppController& aController ) :                                 
       
   236                                  iState( ECamSelfTimerStandby ),
       
   237                                  iController( aController )
       
   238     {                                     
       
   239     iCallback = TCallBack( TimerCallback, this );
       
   240     }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CCamSelfTimer::ConstructL
       
   244 // Symbian 2nd phase constructor can leave.
       
   245 // -----------------------------------------------------------------------------
       
   246 //
       
   247 void CCamSelfTimer::ConstructL()
       
   248     {
       
   249     iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityHigh );    
       
   250     }
       
   251 
       
   252 // -----------------------------------------------------------------------------
       
   253 // CCamSelfTimer::ChangeState
       
   254 // Called to move between the internal self-timer states.
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 void CCamSelfTimer::ChangeState( TCamSelfTimer aState )
       
   258     {  
       
   259     // if the timer object has not been created
       
   260     __ASSERT_DEBUG( iPeriodicTimer != NULL, CamPanic( ECamPanicNullPointer ) );
       
   261 
       
   262     // If the state has been changed
       
   263     iState = aState;
       
   264 
       
   265     switch ( iState )
       
   266         {
       
   267         case ECamSelfTimerActive1:
       
   268             iController.StopIdleTimer(); // no standby mode if time is running
       
   269             iIndication = ETrue;
       
   270             //lint -fallthrough
       
   271         case ECamSelfTimerActive2:
       
   272         case ECamSelfTimerActive3:
       
   273             iTimeRemaining = iSettings.iThreshold[iState];    
       
   274             // Use smallest time period as tick period. This assumes that
       
   275             // smallest time period is divisble into larger time period.
       
   276             iTimerTickPeriod = iSettings.iFlashPeriod[iState];    // Need half-periods
       
   277             if ( iTimerTickPeriod.Int() > iSettings.iBeepPeriod[iState] )
       
   278                 {
       
   279                 iTimerTickPeriod = iSettings.iBeepPeriod[iState];
       
   280                 }
       
   281             
       
   282             if ( iTimerTickPeriod.Int() == KMaxTInt ) // If state is timer based (always on)
       
   283               {
       
   284               iIndication = ETrue;
       
   285               iPeriodicTimer->Cancel();
       
   286               iTimerTickPeriod = iTimeRemaining;// Force period to be time left
       
   287 
       
   288               // Reschedule the timer to go off when the remaining time has completed
       
   289               iPeriodicTimer->Start( iTimeRemaining, iTimeRemaining, iCallback );
       
   290               }
       
   291             else if ( iTimerTickPeriod.Int() == 0 ) // Always off
       
   292               {
       
   293               iIndication = EFalse;
       
   294               iPeriodicTimer->Cancel();
       
   295               iTimerTickPeriod = iTimeRemaining;// Force period to be time left
       
   296 
       
   297               // Reschedule the timer to go off when the remaining time has completed
       
   298               iPeriodicTimer->Start( iTimeRemaining, iTimeRemaining, iCallback );
       
   299               }
       
   300             else if ( iTimerTickPeriod.Int() != KErrNotSupported )    // This is a valid period
       
   301               {
       
   302               TInt period = iTimerTickPeriod.Int();
       
   303               iPeriodicTimer->Cancel();
       
   304               iPeriodicTimer->Start( period, period, iCallback );
       
   305               }
       
   306             // otherwise, do nothing
       
   307             else
       
   308               {
       
   309               // empty statement to remove Lint error.
       
   310               }
       
   311             
       
   312             // Check if we need to start autofocus
       
   313             if ( iSettings.iAutoFocus != KErrNotSupported && 
       
   314                  iTimeRemaining.Int() == iSettings.iAutoFocus )
       
   315               {
       
   316               if ( ECamControllerVideo != iMode )
       
   317                 {
       
   318                 // Start the AutoFocus operation
       
   319                 OstTrace0( CAMERAAPP_PERFORMANCE, CCAMSELFTIMER_CHANGESTATE, "e_CAM_APP_AF 1" );
       
   320                 iController.StartAutoFocus();
       
   321                 }
       
   322               }
       
   323             DoIndication( iIndication );
       
   324             break;
       
   325         
       
   326         case ECamSelfTimerStandby:           
       
   327             iPeriodicTimer->Cancel();
       
   328             if ( !iController.IsSlideInSelfTimerPreview() )
       
   329               {
       
   330               iController.SetDynamicSettingToDefault(ECamSettingItemDynamicSelfTimer);
       
   331               }
       
   332             NotifyObservers( ECamSelfTimerEventTimerOff );
       
   333             break;
       
   334 
       
   335         default:
       
   336             break;
       
   337         }    
       
   338     }
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // TimerCallback Callback used for self timer class to be informed of periodic
       
   342 // timer events
       
   343 // Returns: TInt: KErrNone if successful.
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 TInt CCamSelfTimer::TimerCallback( TAny* aPtr )
       
   347     {
       
   348     CCamSelfTimer* timer = static_cast< CCamSelfTimer* >( aPtr );
       
   349     __ASSERT_DEBUG( timer != NULL, CamPanic( ECamPanicNullPointer ) ); 
       
   350 
       
   351     timer->Tick();        
       
   352 
       
   353     return KErrNone;
       
   354     }
       
   355 
       
   356 // -----------------------------------------------------------------------------
       
   357 // CCamSelfTimer::Tick
       
   358 // Called when the periodic timer "ticks", used to 
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 void CCamSelfTimer::Tick()
       
   362   {
       
   363   PRINT(_L("Camera => CCamSelfTimer::Tick()"));    
       
   364   // Adjust the time remaining
       
   365   iTimeRemaining = iTimeRemaining.Int() - iTimerTickPeriod.Int();
       
   366 
       
   367   // Adjust the time elapsed since last beep and indicator state change.
       
   368   iTimeElapsedSinceIndication += iTimerTickPeriod.Int();
       
   369 
       
   370   // Adjust the indicator state if necessary.
       
   371   __ASSERT_DEBUG( iState < ECamSelfTimerStandby, CamPanic( ECamPanicUnhandledCreateSettingItem ) );
       
   372   if ( iTimeElapsedSinceIndication >= iSettings.iFlashPeriod[iState] )
       
   373     {
       
   374     iIndication = !iIndication;
       
   375     iTimeElapsedSinceIndication = 0;
       
   376     }
       
   377   
       
   378   // If we have reached the end of the timer period...
       
   379   if ( iTimeRemaining == TTimeIntervalMicroSeconds32( 0 ) )
       
   380     {
       
   381     // Cancel the timer, reset internal state.
       
   382     Cancel();
       
   383 
       
   384     // The Controller takes care of the synchronisation of this.
       
   385     // If AutoFocus is complete, start Capture now
       
   386     // If AutoFocus still ongoing, it will wait until autofocus is 
       
   387     // complete THEN Capture.
       
   388     if ( ECamControllerImage == iMode )
       
   389       {  
       
   390       CCamAppUi* appUi = static_cast<CCamAppUi*>( CEikonEnv::Static()->AppUi() );
       
   391       if( appUi )
       
   392         {
       
   393         // Blank all softkeys if doing still capture
       
   394         if ( iImageMode == ECamImageCaptureSingle )
       
   395           {
       
   396           // blank the softkeys in preparation for capture
       
   397           TRAP_IGNORE( appUi->SetSoftKeysL( R_CAM_SOFTKEYS_BLANK ) );
       
   398           }
       
   399                 
       
   400         // Softkeys are blank/cancel if doing burst capture
       
   401         // but cancel means cancel ongoing burst, not cancel self-timer        
       
   402         else if ( ECamImageCaptureBurst     == iImageMode 
       
   403                || ECamImageCaptureTimeLapse == iImageMode )
       
   404           {
       
   405           // blank the softkeys in preparation for capture
       
   406           TRAP_IGNORE( appUi->SetSoftKeysL( R_CAM_SOFTKEYS_BLANK_STOP ) )
       
   407           }
       
   408         }
       
   409 
       
   410       // Ensure everything is OFF
       
   411       DoIndication( EFalse );
       
   412 
       
   413       // Do capture
       
   414       OstTrace0( CAMERAAPP_PERFORMANCE, CCAMSELFTIMER_TICK, "e_CAM_APP_SHOT_TO_SNAPSHOT 1" );
       
   415       OstTrace0( CAMERAAPP_PERFORMANCE, DUP1_CCAMSELFTIMER_TICK, "e_CAM_PRI_SHOT_TO_SNAPSHOT 1" );
       
   416       OstTrace0( CAMERAAPP_PERFORMANCE, DUP2_CCAMSELFTIMER_TICK, "e_CAM_PRI_SHOT_TO_SAVE 1" );
       
   417       OstTrace0( CAMERAAPP_PERFORMANCE, DUP3_CCAMSELFTIMER_TICK, "e_CAM_PRI_SHOT_TO_SHOT 1" );
       
   418       OstTrace0( CAMERAAPP_PERFORMANCE, DUP4_CCAMSELFTIMER_TICK, "e_CAM_APP_SHOT_TO_STILL 1" );
       
   419       OstTrace0( CAMERAAPP_PERFORMANCE, DUP5_CCAMSELFTIMER_TICK, "e_CAM_APP_CAPTURE_START 1" );
       
   420       OstTrace0( CAMERAAPP_PERFORMANCE, DUP6_CCAMSELFTIMER_TICK, "e_CAM_PRI_SERIAL_SHOOTING 1" );
       
   421 
       
   422       iController.Capture();
       
   423       }
       
   424     else // video mode
       
   425       {   
       
   426       TRAP_IGNORE( iController.StartVideoRecordingL() )
       
   427       }            
       
   428     }
       
   429 
       
   430   // The timer is ongoing
       
   431   else 
       
   432     {
       
   433     TInt remaining = iTimeRemaining.Int();
       
   434     // Work out if we need to change period.
       
   435     if ( remaining        == iSettings.iThreshold[ECamSelfTimerActive2] 
       
   436       && KErrNotSupported != iSettings.iThreshold[ECamSelfTimerActive2] )
       
   437       {
       
   438       ChangeState( ECamSelfTimerActive2 );
       
   439       }
       
   440     else if ( remaining        == iSettings.iThreshold[ECamSelfTimerActive3] 
       
   441            && KErrNotSupported != iSettings.iThreshold[ECamSelfTimerActive3])
       
   442       {
       
   443       ChangeState( ECamSelfTimerActive3 );
       
   444       }
       
   445     else
       
   446       {
       
   447       // Update the indicators (done as part of change state as well)
       
   448       DoIndication( iIndication );
       
   449       }
       
   450   
       
   451     // Check if we need to start autofocus
       
   452     if ( KErrNotFound != iSettings.iAutoFocus 
       
   453       && remaining    == iSettings.iAutoFocus )
       
   454       {
       
   455       if ( ECamControllerImage == iMode )
       
   456         {
       
   457         // Start the AutoFocus operation
       
   458         OstTrace0( CAMERAAPP_PERFORMANCE, DUP7_CCAMSELFTIMER_TICK, "e_CAM_APP_AF 1" );
       
   459         iController.StartAutoFocus();
       
   460         }
       
   461       }
       
   462     }
       
   463   PRINT(_L("Camera <= CCamSelfTimer::Tick()"));    
       
   464   }
       
   465 
       
   466 // -----------------------------------------------------------------------------
       
   467 // CCamSelfTimer::DoIndication
       
   468 // Send event to self timer observers
       
   469 // -----------------------------------------------------------------------------
       
   470 //                    
       
   471 void CCamSelfTimer::DoIndication( TBool aOn )
       
   472     {
       
   473     iIndication = aOn;
       
   474 
       
   475     if ( aOn )        
       
   476         {        
       
   477         NotifyObservers( ECamSelfTimerEventTimerOn );
       
   478         iController.PlaySound( ECamSelfTimerSoundId,  EFalse );
       
   479         }
       
   480     else
       
   481         {
       
   482         NotifyObservers( ECamSelfTimerEventTimerOff );
       
   483         }
       
   484     }
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // CCamSelfTimer::AddObserverL
       
   488 // Add a self timer observer 
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 void CCamSelfTimer::AddObserverL( const MCamSelfTimerObserver* aObserver )
       
   492     {
       
   493     User::LeaveIfError( iObservers.Append( aObserver ) );
       
   494     }
       
   495 
       
   496 // -----------------------------------------------------------------------------
       
   497 // CCamSelfTimer::RemoveObserver
       
   498 // Remove a self timer observer
       
   499 // -----------------------------------------------------------------------------
       
   500 //
       
   501 void CCamSelfTimer::RemoveObserver( const MCamSelfTimerObserver* aObserver )
       
   502     {
       
   503     TInt i;
       
   504     TInt numobservers = iObservers.Count();
       
   505     for ( i = 0; i < numobservers; i++ )
       
   506         {
       
   507         // if the observer is the one to remove
       
   508         if ( iObservers[i] == aObserver )
       
   509             {
       
   510             iObservers.Remove( i );
       
   511             return;
       
   512             }
       
   513         }
       
   514     }
       
   515 
       
   516 // -----------------------------------------------------------------------------
       
   517 // CCamSelfTimer::NotifyObservers
       
   518 // Send self timer event to observers
       
   519 // -----------------------------------------------------------------------------
       
   520 //
       
   521 void CCamSelfTimer::NotifyObservers( TCamSelfTimerEvent aEvent )
       
   522     {
       
   523     const TInt KMicroSecsPerSec = 1000000;
       
   524     TInt timeRem = iTimeRemaining.Int() / KMicroSecsPerSec;
       
   525     TInt i;
       
   526     TInt numobservers = iObservers.Count();
       
   527     for ( i = 0; i < numobservers; i++ )
       
   528         {
       
   529         iObservers[i]->HandleSelfTimerEvent( aEvent, timeRem );
       
   530         }
       
   531     }
       
   532 
       
   533 //  End of File