phonebookui/Phonebook2/Application/src/CPbk2StartupMonitor.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     1 /*
       
     2 * Copyright (c) 2005-2007 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:  Phonebook 2 start-up monitor.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CPbk2StartupMonitor.h"
       
    20 
       
    21 // Phonebook 2
       
    22 #include "CPbk2AppUi.h"
       
    23 #include <CPbk2StoreProperty.h>
       
    24 #include <CPbk2StorePropertyArray.h>
       
    25 #include <Pbk2ProcessDecoratorFactory.h>
       
    26 #include <CPbk2AppUiBase.h>
       
    27 #include <Pbk2ViewId.hrh>
       
    28 #include <MPbk2AppUiExtension.h>
       
    29 #include <CPbk2StoreConfiguration.h>
       
    30 #include <MPbk2StartupObserver.h>
       
    31 #include <MPbk2ApplicationServices.h>
       
    32 #include <MPbk2ContactViewSupplier.h>
       
    33 #include <Pbk2UIControls.rsg>
       
    34 #include <Pbk2CommonUi.rsg>
       
    35 #include <CPbk2AppViewBase.h>
       
    36 
       
    37 // Virtual Phonebook
       
    38 #include <MVPbkContactStore.h>
       
    39 #include <MVPbkContactStoreProperties.h>
       
    40 #include <MVPbkContactViewBase.h>
       
    41 #include <CVPbkContactStoreUriArray.h>
       
    42 #include <MVPbkContactStoreList.h>
       
    43 #include <CVPbkContactManager.h>
       
    44 
       
    45 // System includes
       
    46 #include <StringLoader.h>
       
    47 #include <aknnotewrappers.h>
       
    48 #include <aknview.h>
       
    49 
       
    50 // Debugging headers
       
    51 #include <Pbk2Debug.h>
       
    52 
       
    53 const TInt KOneSecond = 1000000;
       
    54 const TInt KGranularity = 4;
       
    55 
       
    56 /// Unnamed namespace for local definitions
       
    57 namespace {
       
    58 
       
    59 #ifdef _DEBUG
       
    60 
       
    61 enum TPanicCode
       
    62     {
       
    63     EPanicNullPointer = 1,
       
    64     };
       
    65 
       
    66 void Panic(TPanicCode aReason)
       
    67     {
       
    68     _LIT( KPanicText, "CPbk2StartupMonitor" );
       
    69     User::Panic(KPanicText,aReason);
       
    70     }
       
    71 
       
    72 #endif // _DEBUG
       
    73 
       
    74 } /// namespace
       
    75 
       
    76 /**
       
    77  * Utility class that implements the wait logic and
       
    78  * process decoration if needed.
       
    79  */
       
    80 class CPbk2StartupMonitor::CPbk2StartupWaiter :
       
    81         public CTimer,
       
    82         private MPbk2ProcessDecoratorObserver
       
    83 
       
    84     {
       
    85     public: // Construction and destruction
       
    86 
       
    87         /**
       
    88          * Creates a new instance of this class.
       
    89          *
       
    90          * @return  A new instance of this class.
       
    91          */
       
    92         static CPbk2StartupWaiter* NewL();
       
    93 
       
    94         /**
       
    95          * Destructor.
       
    96          */
       
    97         ~CPbk2StartupWaiter();
       
    98 
       
    99     public: // Interface
       
   100 
       
   101         /**
       
   102          * Stops the monitor.
       
   103          */
       
   104         void Stop();
       
   105         
       
   106         /**
       
   107          * Restart monitor. 
       
   108          */
       
   109         void Restart();
       
   110         
       
   111         /**
       
   112          * Disables wait note if waiter is started.
       
   113          */
       
   114         void DisableWaitNote();
       
   115         
       
   116     private: // From CTimer
       
   117         void RunL();
       
   118         TInt RunError(
       
   119                 TInt aError );
       
   120 
       
   121     private: // From MPbk2ProcessDecoratorObserver
       
   122         void ProcessDismissed(
       
   123                 TInt aCancelCode );
       
   124 
       
   125     private: // Implementation
       
   126         CPbk2StartupWaiter();
       
   127         void ConstructL();
       
   128 
       
   129     private: // Data
       
   130         /// Own: Decorator for the process
       
   131         MPbk2ProcessDecorator* iDecorator;
       
   132         /// Is decorator launched
       
   133         TBool iStarted;
       
   134         /// Own: There are exception that even if monitor is started
       
   135         /// wait note should not be displayed.
       
   136         TBool iDisplayWaitNote;
       
   137     };
       
   138 
       
   139 // --------------------------------------------------------------------------
       
   140 // CPbk2StartupMonitor::CPbk2StartupWaiter::CPbk2StartupWaiter
       
   141 // EPriorityHigh because the timer must not be delayed due to other
       
   142 // active objects in this thread.
       
   143 // --------------------------------------------------------------------------
       
   144 //
       
   145 CPbk2StartupMonitor::CPbk2StartupWaiter::CPbk2StartupWaiter() :
       
   146         CTimer( CActive::EPriorityHigh )
       
   147     {
       
   148     CActiveScheduler::Add(this);
       
   149     }
       
   150 
       
   151 // --------------------------------------------------------------------------
       
   152 // CPbk2StartupMonitor::CPbk2StartupWaiter::~CPbk2StartupWaiter
       
   153 // --------------------------------------------------------------------------
       
   154 //
       
   155 CPbk2StartupMonitor::CPbk2StartupWaiter::~CPbk2StartupWaiter()
       
   156     {
       
   157     Cancel();
       
   158     delete iDecorator;
       
   159     }
       
   160 
       
   161 // --------------------------------------------------------------------------
       
   162 // CPbk2StartupMonitor::CPbk2StartupWaiter::ConstructL
       
   163 // --------------------------------------------------------------------------
       
   164 //
       
   165 inline void CPbk2StartupMonitor::CPbk2StartupWaiter::ConstructL()
       
   166     {
       
   167     CTimer::ConstructL();
       
   168 
       
   169     // According to the Notes specification the wait note is showed if the
       
   170     // operation takes more than a second. And when it's showed it should
       
   171     // be visible at least 1,5 seconds. In our case the operation starts
       
   172     // when the first view is launched i.e. the view's DoActivateL notifies
       
   173     // the start up monitor.
       
   174     // Wait KOneSecond and then launch the wait note without delay.
       
   175     After( TTimeIntervalMicroSeconds32( KOneSecond ) );
       
   176     iDisplayWaitNote = ETrue;
       
   177     }
       
   178 
       
   179 // --------------------------------------------------------------------------
       
   180 // CPbk2StartupMonitor::CPbk2StartupWaiter::NewL
       
   181 // --------------------------------------------------------------------------
       
   182 //
       
   183 CPbk2StartupMonitor::CPbk2StartupWaiter*
       
   184         CPbk2StartupMonitor::CPbk2StartupWaiter::NewL()
       
   185     {
       
   186     CPbk2StartupMonitor::CPbk2StartupWaiter* self =
       
   187         new ( ELeave ) CPbk2StartupMonitor::CPbk2StartupWaiter();
       
   188     CleanupStack::PushL( self );
       
   189     self->ConstructL();
       
   190     CleanupStack::Pop( self );
       
   191     return self;
       
   192     }
       
   193 
       
   194 // --------------------------------------------------------------------------
       
   195 // CPbk2StartupMonitor::CPbk2StartupWaiter::Stop
       
   196 // --------------------------------------------------------------------------
       
   197 //
       
   198 void CPbk2StartupMonitor::CPbk2StartupWaiter::Stop()
       
   199     {
       
   200     Cancel();
       
   201     if ( iDecorator )
       
   202         {
       
   203         iDecorator->ProcessStopped();
       
   204         }
       
   205     iDisplayWaitNote = ETrue;
       
   206     }
       
   207 
       
   208 // --------------------------------------------------------------------------
       
   209 // CPbk2StartupMonitor::CPbk2StartupWaiter::Restart
       
   210 // --------------------------------------------------------------------------
       
   211 //
       
   212 void CPbk2StartupMonitor::CPbk2StartupWaiter::Restart()
       
   213     {
       
   214     Cancel();
       
   215     After( TTimeIntervalMicroSeconds32( KOneSecond ) );
       
   216     }
       
   217 
       
   218 // --------------------------------------------------------------------------
       
   219 // CPbk2StartupMonitor::CPbk2StartupWaiter::DisableWaitNote
       
   220 // --------------------------------------------------------------------------
       
   221 //
       
   222 void CPbk2StartupMonitor::CPbk2StartupWaiter::DisableWaitNote()
       
   223     {
       
   224     iDisplayWaitNote = EFalse;
       
   225     }
       
   226 
       
   227 // --------------------------------------------------------------------------
       
   228 // CPbk2StartupMonitor::CPbk2StartupWaiter::RunL
       
   229 // --------------------------------------------------------------------------
       
   230 //
       
   231 void CPbk2StartupMonitor::CPbk2StartupWaiter::RunL()
       
   232     {
       
   233     // Timer has elapsed
       
   234     if( !iDecorator )
       
   235     	{
       
   236 		iDecorator = Pbk2ProcessDecoratorFactory::CreateWaitNoteDecoratorL
       
   237 				( R_QTN_FDN_READING_MEMORY_WAIT_NOTE, EFalse );
       
   238 		iDecorator->SetObserver(*this);
       
   239     	}
       
   240     if( !iStarted && iDisplayWaitNote ) // don't start twice
       
   241     	{
       
   242 		const TInt dummy = 0; // wait note doesn't care about amount
       
   243 		iDecorator->ProcessStartedL(dummy);
       
   244 		iStarted = ETrue;
       
   245     	}
       
   246     iDisplayWaitNote = ETrue;
       
   247     }
       
   248 
       
   249 // --------------------------------------------------------------------------
       
   250 // CPbk2StartupMonitor::CPbk2StartupWaiter::RunError
       
   251 // --------------------------------------------------------------------------
       
   252 //
       
   253 TInt CPbk2StartupMonitor::CPbk2StartupWaiter::RunError( TInt aError )
       
   254     {
       
   255     CCoeEnv::Static()->HandleError(aError);
       
   256     iStarted = EFalse;
       
   257     iDisplayWaitNote = ETrue;
       
   258     if (iDecorator)
       
   259         {
       
   260         iDecorator->ProcessStopped();
       
   261         }
       
   262     return KErrNone;
       
   263     }
       
   264 
       
   265 // --------------------------------------------------------------------------
       
   266 // CPbk2StartupMonitor::CPbk2StartupWaiter::ProcessDismissed
       
   267 // --------------------------------------------------------------------------
       
   268 //
       
   269 void CPbk2StartupMonitor::CPbk2StartupWaiter::ProcessDismissed
       
   270         ( TInt aCancelCode )
       
   271     {
       
   272     iStarted = EFalse;
       
   273     if ( aCancelCode == EAknSoftkeyCancel )
       
   274         {
       
   275         CPbk2AppUi& appUi = static_cast<CPbk2AppUi&>
       
   276             ( *CEikonEnv::Static()->EikAppUi() );
       
   277 
       
   278         appUi.RunAppShutter();
       
   279         }
       
   280     }
       
   281 
       
   282 // --------------------------------------------------------------------------
       
   283 // CPbk2StartupMonitor::CPbk2StartupMonitor
       
   284 // --------------------------------------------------------------------------
       
   285 //
       
   286 CPbk2StartupMonitor::CPbk2StartupMonitor
       
   287         ( MPbk2AppUiExtension& aAppUiExtension,
       
   288           CPbk2StorePropertyArray& aStoreProperties,
       
   289           CPbk2StoreConfiguration& aStoreConfiguration,
       
   290           CVPbkContactManager& aContactManager ) :
       
   291             iAppUiExtension( aAppUiExtension ),
       
   292             iStoreProperties( aStoreProperties ),
       
   293             iStoreConfiguration( aStoreConfiguration ),
       
   294             iContactManager( aContactManager ),
       
   295             iFirstViewId( TUid::Uid( EPbk2NullViewId ) )
       
   296     {
       
   297     }
       
   298 
       
   299 // --------------------------------------------------------------------------
       
   300 // CPbk2StartupMonitor::~CPbk2StartupMonitor
       
   301 // --------------------------------------------------------------------------
       
   302 //
       
   303 CPbk2StartupMonitor::~CPbk2StartupMonitor()
       
   304     {
       
   305     delete iStoreUris;
       
   306     delete iUnavailableStoreNames;
       
   307     delete iWaiter;
       
   308     delete iIdleNotifier;
       
   309     iObservers.Close();
       
   310     }
       
   311 
       
   312 // --------------------------------------------------------------------------
       
   313 // CPbk2StartupMonitor::ConstructL
       
   314 // --------------------------------------------------------------------------
       
   315 //
       
   316 inline void CPbk2StartupMonitor::ConstructL()
       
   317     {
       
   318     iIdleNotifier = CIdle::NewL( CActive::EPriorityIdle );
       
   319     }
       
   320 
       
   321 // --------------------------------------------------------------------------
       
   322 // CPbk2StartupMonitor::NewL
       
   323 // --------------------------------------------------------------------------
       
   324 //
       
   325 CPbk2StartupMonitor* CPbk2StartupMonitor::NewL
       
   326         ( MPbk2AppUiExtension& aAppUiExtension,
       
   327           CPbk2StorePropertyArray& aStoreProperties,
       
   328           CPbk2StoreConfiguration& aStoreConfiguration,
       
   329           CVPbkContactManager& aContactManager )
       
   330     {
       
   331     CPbk2StartupMonitor* self = new ( ELeave ) CPbk2StartupMonitor
       
   332         ( aAppUiExtension, aStoreProperties,
       
   333           aStoreConfiguration, aContactManager );
       
   334     CleanupStack::PushL( self );
       
   335     self->ConstructL();
       
   336     CleanupStack::Pop( self );
       
   337     return self;
       
   338     }
       
   339 
       
   340 // --------------------------------------------------------------------------
       
   341 // CPbk2StartupMonitor::StartupBeginsL
       
   342 // --------------------------------------------------------------------------
       
   343 //
       
   344 void CPbk2StartupMonitor::StartupBeginsL()
       
   345     {
       
   346     // Well, actually start up monitor runs when first application view is
       
   347     // activated in NotifyViewActivationL but let the UI extensions start
       
   348     // their task before that.
       
   349     iIdleNotifier->Cancel();
       
   350     iAppUiExtension.ExtensionStartupL( *this );
       
   351     }
       
   352 
       
   353 // --------------------------------------------------------------------------
       
   354 // CPbk2StartupMonitor::RestartStartupL
       
   355 // --------------------------------------------------------------------------
       
   356 //
       
   357 void CPbk2StartupMonitor::RestartStartupL()
       
   358     {
       
   359     
       
   360     //Updated Functionality (EHKN-7RRBR8):
       
   361     //When PB goes to background or foreground, its not necessary to be in 
       
   362     //EPbk2NamesListViewId. It can be even in the xspview.
       
   363     //Hence only if the Active view was EPbk2NamesListViewId, we need to emulate
       
   364     //the view activation of EPbk2NamesListViewId.
       
   365     //By this way we can reduce the unnecessary note which gets shown
       
   366     //in xsp views. Leave it to xsp views what to do when this happens
       
   367     
       
   368     //Previous Functionality :
       
   369     // This function is used in "Always On" mode. When application goes
       
   370     // background it activates EPbk2NamesListViewId. When coming back to
       
   371     // foreground again we need to emulate the view activation of
       
   372     // EPbk2NamesListViewId.
       
   373     
       
   374     //Fix for TSW Err : EHKN-7RRBR8 "Checking contacts" shown when selecting search for WLAN
       
   375     CPbk2AppViewBase* activeView = Phonebook2::Pbk2AppUi()->ActiveView();
       
   376     TUid activeViewId ( TUid::Uid( EPbk2NullViewId ) );
       
   377     if ( activeView )
       
   378         {
       
   379         activeViewId = activeView->Id();
       
   380         }
       
   381     
       
   382     if ( 
       
   383             ( iFirstViewId != TUid::Uid( EPbk2NullViewId ) ) &&
       
   384             //Perform the Startup monitor only of its the PhoneBook Views
       
   385             //exclude the xsp views
       
   386             ( IsNativePhoneBookView( activeViewId ) )
       
   387         )
       
   388         {
       
   389         TBool isMonitorActive = ( iStoreUris && iStoreUris->Count() > 0 );
       
   390         if ( !isMonitorActive )
       
   391             {
       
   392             StartupBeginsL();
       
   393             // Reset the first application view id and then call
       
   394             // NotifyViewActivationL as it would be called from
       
   395             // the DoActivateL.
       
   396             iFirstViewId = TUid::Uid( EPbk2NullViewId );
       
   397             NotifyViewActivationL( TUid::Uid( EPbk2NamesListViewId ) );
       
   398             }
       
   399         }
       
   400     }
       
   401 
       
   402 // --------------------------------------------------------------------------
       
   403 // CPbk2StartupMonitor::HandleStartupComplete
       
   404 // --------------------------------------------------------------------------
       
   405 //
       
   406 void CPbk2StartupMonitor::HandleStartupComplete()
       
   407     {
       
   408     // Core Phonebook2 is not actually interested of others because it
       
   409     // it wants that the start up is as fast as possible.
       
   410     // E.g if a UI extension is doing something heavy in the start up
       
   411     // it will not cause delay to user.
       
   412     }
       
   413 
       
   414 // --------------------------------------------------------------------------
       
   415 // CPbk2StartupMonitor::HandleStartupFailed
       
   416 // --------------------------------------------------------------------------
       
   417 //
       
   418 void CPbk2StartupMonitor::HandleStartupFailed( TInt aError )
       
   419     {
       
   420     HandleError( aError );
       
   421     }
       
   422 
       
   423 // --------------------------------------------------------------------------
       
   424 // CPbk2StartupMonitor::RegisterEventsL
       
   425 // --------------------------------------------------------------------------
       
   426 //
       
   427 void CPbk2StartupMonitor::RegisterEventsL( MPbk2StartupObserver& aObserver )
       
   428     {
       
   429     if (iObservers.Find(&aObserver) == KErrNotFound)
       
   430         {
       
   431         iObservers.AppendL(&aObserver);
       
   432         }
       
   433     }
       
   434 
       
   435 // --------------------------------------------------------------------------
       
   436 // CPbk2StartupMonitor::DeregisterEvents
       
   437 // --------------------------------------------------------------------------
       
   438 //
       
   439 void CPbk2StartupMonitor::DeregisterEvents( MPbk2StartupObserver& aObserver )
       
   440     {
       
   441     TInt pos = iObservers.Find(&aObserver);
       
   442     if (pos != KErrNotFound)
       
   443         {
       
   444         iObservers.Remove(pos);
       
   445         }
       
   446     }
       
   447 
       
   448 // --------------------------------------------------------------------------
       
   449 // CPbk2StartupMonitor::NotifyViewActivationL
       
   450 // --------------------------------------------------------------------------
       
   451 //
       
   452 void CPbk2StartupMonitor::NotifyViewActivationL( TUid aViewId )
       
   453     {
       
   454     // Default is: wait all contacts view.
       
   455     NotifyViewActivationL( aViewId,
       
   456             *Phonebook2::Pbk2AppUi()->ApplicationServices().
       
   457                 ViewSupplier().AllContactsViewL() );
       
   458     }
       
   459 
       
   460 // --------------------------------------------------------------------------
       
   461 // CPbk2StartupMonitor::NotifyViewActivationL
       
   462 // --------------------------------------------------------------------------
       
   463 //
       
   464 void CPbk2StartupMonitor::NotifyViewActivationL( TUid aViewId,
       
   465         MVPbkContactViewBase& aContactView )
       
   466     {
       
   467     if ( iFirstViewId == TUid::Uid( EPbk2NullViewId ) )
       
   468         {
       
   469         // Start monitor actions only if it hasn't been notified before.
       
   470         // Only the first application view activation is important for
       
   471         // the monitor.
       
   472         iFirstViewId = aViewId;
       
   473         // Start listening to store events
       
   474         RegisterStoreEventsForViewL( aContactView );
       
   475         // Don't start anything if there are no stores to listen.
       
   476         if ( iStoreUris && iStoreUris->Count() > 0 )
       
   477             {
       
   478             // Start wait note with delay
       
   479             if( !iWaiter )
       
   480             	{
       
   481             	iWaiter = CPbk2StartupWaiter::NewL();
       
   482             	}
       
   483             else
       
   484             	{
       
   485 				iWaiter->Restart();
       
   486             	}
       
   487             // Start listening to view events
       
   488             aContactView.AddObserverL( *this );
       
   489             }
       
   490         else
       
   491             {
       
   492             // There is no view/store events coming to monitor so send
       
   493             // completion event to monitor's observers.
       
   494             StartAsyncCompletionNotification();
       
   495 			StopWaiter();
       
   496             }
       
   497         }
       
   498     }
       
   499 
       
   500 // --------------------------------------------------------------------------
       
   501 // CPbk2StartupMonitor::StoreReady
       
   502 // --------------------------------------------------------------------------
       
   503 //
       
   504 void CPbk2StartupMonitor::StoreReady(MVPbkContactStore& aContactStore)
       
   505     {
       
   506     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   507         ("CPbk2StartupMonitor::StoreReady(0x%x)"), this);
       
   508 
       
   509     TRAPD( res, HandleStoreNotificationL( aContactStore ) );
       
   510     HandleError( res );
       
   511     }
       
   512 
       
   513 // --------------------------------------------------------------------------
       
   514 // CPbk2StartupMonitor::StoreUnavailable
       
   515 // --------------------------------------------------------------------------
       
   516 //
       
   517 void CPbk2StartupMonitor::StoreUnavailable
       
   518         ( MVPbkContactStore& aContactStore, TInt /*aReason*/ )
       
   519     {
       
   520     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   521         ("CPbk2StartupMonitor::StoreUnavailable(0x%x)"), this);
       
   522 
       
   523     TRAPD( res, HandleStoreUnavailableL( aContactStore ) );
       
   524     HandleError( res );
       
   525     }
       
   526 
       
   527 // --------------------------------------------------------------------------
       
   528 // CPbk2StartupMonitor::HandleStoreEventL
       
   529 // --------------------------------------------------------------------------
       
   530 //
       
   531 void CPbk2StartupMonitor::HandleStoreEventL(
       
   532         MVPbkContactStore& /*aContactStore*/,
       
   533         TVPbkContactStoreEvent /*aStoreEvent*/ )
       
   534     {
       
   535     // Monitor is interested only in unavailable events
       
   536     }
       
   537 
       
   538 // --------------------------------------------------------------------------
       
   539 // CPbk2StartupMonitor::ContactViewReady
       
   540 // --------------------------------------------------------------------------
       
   541 //
       
   542 void CPbk2StartupMonitor::ContactViewReady( MVPbkContactViewBase& aView )
       
   543     {
       
   544     TRAPD( res, HandleContactViewReadyEventL( aView ) );
       
   545     HandleError( res );
       
   546     }
       
   547 
       
   548 // --------------------------------------------------------------------------
       
   549 // CPbk2StartupMonitor::ContactViewUnavailable
       
   550 // --------------------------------------------------------------------------
       
   551 //
       
   552 void CPbk2StartupMonitor::ContactViewUnavailable
       
   553         ( MVPbkContactViewBase& /*aView*/ )
       
   554     {
       
   555     // Monitor is only interestend in  view ready event. The monitor also
       
   556     // listens to store events so it's ok to ignore view unavailable
       
   557     // because monitor will stop if non of the stores are available.
       
   558     }
       
   559 
       
   560 // --------------------------------------------------------------------------
       
   561 // CPbk2StartupMonitor::ContactAddedToView
       
   562 // --------------------------------------------------------------------------
       
   563 //
       
   564 void CPbk2StartupMonitor::ContactAddedToView
       
   565         ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
       
   566           const MVPbkContactLink& /*aContactLink*/ )
       
   567     {
       
   568     // Monitor is interested only in view ready event
       
   569     }
       
   570 
       
   571 // --------------------------------------------------------------------------
       
   572 // CPbk2StartupMonitor::ContactRemovedFromView
       
   573 // --------------------------------------------------------------------------
       
   574 //
       
   575 void CPbk2StartupMonitor::ContactRemovedFromView
       
   576         ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
       
   577           const MVPbkContactLink& /*aContactLink*/ )
       
   578     {
       
   579     // Monitor is interested only in view ready event
       
   580     }
       
   581 
       
   582 // --------------------------------------------------------------------------
       
   583 // CPbk2StartupMonitor::ContactViewError
       
   584 // --------------------------------------------------------------------------
       
   585 //
       
   586 void CPbk2StartupMonitor::ContactViewError
       
   587         ( MVPbkContactViewBase& /*aView*/, TInt /*aError*/,
       
   588           TBool /*aErrorNotified*/ )
       
   589     {
       
   590     // Monitor is interested only in view ready event
       
   591     }
       
   592 
       
   593 // --------------------------------------------------------------------------
       
   594 // CPbk2StartupMonitor::AddUnavailableStoreNameL
       
   595 // --------------------------------------------------------------------------
       
   596 //
       
   597 void CPbk2StartupMonitor::AddUnavailableStoreNameL(const TDesC& aName)
       
   598     {
       
   599     if (!iUnavailableStoreNames)
       
   600         {
       
   601         iUnavailableStoreNames = new(ELeave) CDesCArrayFlat(KGranularity);
       
   602         }
       
   603 
       
   604     TInt dummy = 0;
       
   605     if (iUnavailableStoreNames->Find(aName, dummy) != 0)
       
   606         {
       
   607         iUnavailableStoreNames->AppendL(aName);
       
   608         }
       
   609     }
       
   610 
       
   611 // --------------------------------------------------------------------------
       
   612 // CPbk2StartupMonitor::ShowUnavailableStoresL
       
   613 // --------------------------------------------------------------------------
       
   614 //
       
   615 void CPbk2StartupMonitor::ShowUnavailableStoresL()
       
   616     {
       
   617     if (iUnavailableStoreNames)
       
   618         {
       
   619         const TInt count = iUnavailableStoreNames->MdcaCount();
       
   620         for (TInt i = 0; i < count ;++i)
       
   621             {
       
   622             // The constructor of CAknInformationNote with an argument of 
       
   623             // ETrue will create a Wait Dialog for it which finally 
       
   624             // introduces an object of CActiveSchedulerWait that may 
       
   625             // make this function reentered by another Active Object. 
       
   626             // This AO may delete iUnavailableStoreNames and make it 
       
   627             // no longer available, and if following codes isn't aware 
       
   628             // the action, any function call via the invalid pointer 
       
   629             // surely makes the application crash.
       
   630             // Always check the pointer if it's NULL before using it.
       
   631             if (iUnavailableStoreNames)
       
   632                 {
       
   633                 // Get the store name
       
   634                 HBufC* text = StringLoader::LoadLC
       
   635                     ( R_QTN_PHOB_STORE_NOT_AVAILABLE,
       
   636                       iUnavailableStoreNames->MdcaPoint( i ) );
       
   637                 CAknInformationNote* note =
       
   638                     new ( ELeave ) CAknInformationNote( ETrue );
       
   639                 // Show "not available" note
       
   640                 note->ExecuteLD(*text);
       
   641                 CleanupStack::PopAndDestroy(text);
       
   642                 }
       
   643             }
       
   644         // Destroy when used
       
   645         delete iUnavailableStoreNames;
       
   646         iUnavailableStoreNames = NULL;
       
   647         }
       
   648     }
       
   649 
       
   650 // --------------------------------------------------------------------------
       
   651 // CPbk2StartupMonitor::HandleStoreUnavailableL
       
   652 // --------------------------------------------------------------------------
       
   653 //
       
   654 void CPbk2StartupMonitor::HandleStoreUnavailableL(
       
   655         MVPbkContactStore& aContactStore )
       
   656     {
       
   657     // Get the property of the failed store
       
   658     const CPbk2StoreProperty* prop = iStoreProperties.FindProperty(
       
   659             aContactStore.StoreProperties().Uri() );
       
   660 
       
   661     if ( prop && prop->StoreName().Length() > 0 )
       
   662         {
       
   663         // Use localised store name if found.
       
   664         AddUnavailableStoreNameL( prop->StoreName() );
       
   665         }
       
   666     else
       
   667         {
       
   668         // Use store URI if there was no name.
       
   669         AddUnavailableStoreNameL(
       
   670                 aContactStore.StoreProperties().Uri().UriDes() );
       
   671         }
       
   672 
       
   673     HandleStoreNotificationL( aContactStore );
       
   674     }
       
   675 
       
   676 // --------------------------------------------------------------------------
       
   677 // CPbk2StartupMonitor::HandleStoreNotificationL
       
   678 // --------------------------------------------------------------------------
       
   679 //
       
   680 void CPbk2StartupMonitor::HandleStoreNotificationL(
       
   681         MVPbkContactStore& aContactStore )
       
   682     {
       
   683     TVPbkContactStoreUriPtr uri = aContactStore.StoreProperties().Uri();
       
   684     DeregisterStoreEventsL( uri );
       
   685     iStoreUris->Remove( uri );
       
   686     if ( iStoreUris->Count() == 0 )
       
   687         {
       
   688         // Wait note is dismissed when all stores have send notifications.
       
   689         StopWaiter();
       
   690         // Show notes for the stores that were not available.
       
   691         ShowUnavailableStoresL();
       
   692         // Send monitor events to observers.
       
   693         StartAsyncCompletionNotification();
       
   694         }
       
   695     }
       
   696 
       
   697 // --------------------------------------------------------------------------
       
   698 // CPbk2StartupMonitor::HandleContactViewReadyEventL
       
   699 // --------------------------------------------------------------------------
       
   700 //
       
   701 void CPbk2StartupMonitor::HandleContactViewReadyEventL(
       
   702         MVPbkContactViewBase& aContactView )
       
   703     {
       
   704     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   705         ("CPbk2StartupMonitor::HandleContactViewReadyEventL(0x%x)"), this);
       
   706 
       
   707     // We can not trust that view event ever arrives because client might
       
   708     // have deleted the view. The monitor actions are not completed because
       
   709     // of that. It's done when all stores have send notifications. This
       
   710     // kind of logic assumes that building a view is quite fast
       
   711     // after the stores are ready.
       
   712     aContactView.RemoveObserver( *this );
       
   713     // Wait note is dismissed when the view is ready. This is because the
       
   714     // composite contact view is ready when the first sub view is ready
       
   715     // and application doesn't want to wait the slowest sub view.
       
   716     StopWaiter();
       
   717     }
       
   718 
       
   719 // --------------------------------------------------------------------------
       
   720 // CPbk2StartupMonitor::SendMessageToObservers
       
   721 // --------------------------------------------------------------------------
       
   722 //
       
   723 TInt CPbk2StartupMonitor::SendMessageToObservers( TAny* aSelf )
       
   724     {
       
   725     __ASSERT_DEBUG( aSelf, Panic(EPanicNullPointer));
       
   726 
       
   727     CPbk2StartupMonitor* self = static_cast<CPbk2StartupMonitor*>( aSelf );
       
   728 
       
   729     const TInt count = self->iObservers.Count();
       
   730     TRAPD( res,
       
   731         {
       
   732         for ( TInt i = 0; i < count; ++i )
       
   733             {
       
   734             self->iObservers[i]->ContactUiReadyL( *self );
       
   735             }
       
   736         });
       
   737     self->HandleError( res );
       
   738 
       
   739     // Don't continue
       
   740     return 0;
       
   741     }
       
   742 
       
   743 // --------------------------------------------------------------------------
       
   744 // CPbk2StartupMonitor::HandleError
       
   745 // This function is used for errors that happens in this class. If store
       
   746 // or view sends an error it's not to be handle by this class.
       
   747 // --------------------------------------------------------------------------
       
   748 //
       
   749 void CPbk2StartupMonitor::HandleError( TInt aResult )
       
   750     {
       
   751     if (aResult != KErrNone)
       
   752         {
       
   753         // Stop the wait note
       
   754         StopWaiter();
       
   755         // Show default error note
       
   756         CCoeEnv::Static()->HandleError(aResult);
       
   757         // We are in the middle of start up so better to shut it down than
       
   758         // continue.
       
   759         iAvkonAppUi->RunAppShutter();
       
   760         }
       
   761     }
       
   762 
       
   763 // --------------------------------------------------------------------------
       
   764 // CPbk2StartupMonitor::StopWaiter
       
   765 // --------------------------------------------------------------------------
       
   766 //
       
   767 void CPbk2StartupMonitor::StopWaiter()
       
   768     {
       
   769     if (iWaiter)
       
   770         {
       
   771         iWaiter->Stop();
       
   772         }
       
   773     }
       
   774 
       
   775 // --------------------------------------------------------------------------
       
   776 // CPbk2StartupMonitor::RegisterStoreEventsForViewL
       
   777 // --------------------------------------------------------------------------
       
   778 //
       
   779 void CPbk2StartupMonitor::RegisterStoreEventsForViewL
       
   780         ( MVPbkContactViewBase& aContactView )
       
   781     {
       
   782     // Monitor is interested only stores that are in current config
       
   783     delete iStoreUris;
       
   784     iStoreUris = NULL;
       
   785     // Get all supported URIs in Pbk2
       
   786     iStoreUris = iStoreConfiguration.SupportedStoreConfigurationL();
       
   787     // Open all stores in current config to get their state.
       
   788     const TInt count = iStoreUris->Count();
       
   789 
       
   790     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   791         ("CPbk2StartupMonitor::RestartStartupL(0x%x) [%d]"), this, count);
       
   792 
       
   793     MVPbkContactStoreList& stores = iContactManager.ContactStoresL();
       
   794 
       
   795     // Start listening every store that is used in aContactView and
       
   796     // is found from iContactManager. Do not load stores to contact
       
   797     // manager because it's not start-up monitor's responsibility.
       
   798     for ( TInt i = count - 1; i >= 0; --i )
       
   799         {
       
   800         TVPbkContactStoreUriPtr uriPtr( (*iStoreUris)[i] );
       
   801         MVPbkContactStore* store = stores.Find( uriPtr );
       
   802         if ( store && aContactView.MatchContactStore( uriPtr.UriDes() ) )
       
   803             {
       
   804             store->OpenL( *this );
       
   805             }
       
   806         else
       
   807             {
       
   808             iStoreUris->Remove( uriPtr );
       
   809             }
       
   810         }
       
   811     }
       
   812 
       
   813 // --------------------------------------------------------------------------
       
   814 // CPbk2StartupMonitor::DeregisterStoreEventsL
       
   815 // --------------------------------------------------------------------------
       
   816 //
       
   817 void CPbk2StartupMonitor::DeregisterStoreEventsL
       
   818         ( TVPbkContactStoreUriPtr aUri )
       
   819     {
       
   820     MVPbkContactStoreList& stores = iContactManager.ContactStoresL();
       
   821     MVPbkContactStore* store = stores.Find( aUri );
       
   822     if ( store )
       
   823         {
       
   824         store->Close( *this );
       
   825         }
       
   826     }
       
   827 
       
   828 // --------------------------------------------------------------------------
       
   829 // CPbk2StartupMonitor::StartAsyncCompletionNotification
       
   830 // --------------------------------------------------------------------------
       
   831 //
       
   832 void CPbk2StartupMonitor::StartAsyncCompletionNotification()
       
   833     {
       
   834     iIdleNotifier->Cancel();
       
   835     iIdleNotifier->Start( TCallBack( &SendMessageToObservers, this ));
       
   836     }
       
   837 
       
   838 // --------------------------------------------------------------------------
       
   839 // CPbk2StartupMonitor::IsNativePhoneBookView
       
   840 // --------------------------------------------------------------------------
       
   841 //
       
   842 //See Pbk2ViewId.hrh
       
   843 TBool CPbk2StartupMonitor::IsNativePhoneBookView( TUid aActiveViewId )
       
   844     {
       
   845     TBool nativePhoneBookView = EFalse;
       
   846     for ( TInt index = EPbk2NullViewId; index <= EPbk2SettingsViewId; index++ )
       
   847         {
       
   848         if ( aActiveViewId == TUid::Uid( index ) )
       
   849             {
       
   850             nativePhoneBookView = ETrue;
       
   851             break;
       
   852             }
       
   853         }
       
   854     
       
   855     return nativePhoneBookView;
       
   856     }
       
   857 
       
   858 // --------------------------------------------------------------------------
       
   859 // CPbk2StartupMonitor::Extension
       
   860 // --------------------------------------------------------------------------
       
   861 //
       
   862 TAny* CPbk2StartupMonitor::StartupMonitorExtension( TUid aExtensionUid )
       
   863     {
       
   864     if( aExtensionUid == KPbk2StartupMonitorExtensionUid )
       
   865         {
       
   866         return static_cast<MPbk2StartupMonitorExtension*>( this );
       
   867         }
       
   868     return NULL;
       
   869     }
       
   870 
       
   871 // --------------------------------------------------------------------------
       
   872 // CPbk2StartupMonitor::DisableWaitNote
       
   873 // --------------------------------------------------------------------------
       
   874 //
       
   875 void  CPbk2StartupMonitor::DisableMonitoring()
       
   876     {
       
   877     iWaiter->DisableWaitNote();
       
   878     }
       
   879 
       
   880 // End of File