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