--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/cntmodel/src/CCntNotificationMonitor.cpp Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,216 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#include "ccontactprivate.h"
+#include "CCntNotificationMonitor.h"
+#include "rcntmodel.h"
+
+
+extern void DebugLogNotification(const TDesC& aMethod, const TContactDbObserverEvent &aEvent);
+
+
+CCntNotificationMonitor::CCntNotificationMonitor(RCntModel& aSession)
+ : CActive(EPriorityStandard), iSession(aSession)
+ {}
+
+
+CCntNotificationMonitor::~CCntNotificationMonitor()
+ {
+ Cancel();
+ }
+
+
+void CCntNotificationMonitor::DoCancel()
+ {
+ // TRequestStatus* status = &iStatus;
+ // User::RequestComplete(status, KErrNone);
+ }
+
+
+/**
+This method is called each time the request for an event from the Server is
+completed.
+*/
+void CCntDbNotifyMonitor::RunL()
+ {
+ if ( iStatus == KErrDied || iStatus == KErrServerTerminated )
+ {
+ // We have lost our connection to the Server. Attempt to restart it,
+ // reconnect the session and open the Contacts database.
+ iSession.HandlePrematureServerTerminationL();
+ // Request another event.
+ Start();
+ return;
+ }
+
+
+
+
+ TInt count = iObserverArray.Count();
+ TContactDbObserverEvent& event = iEventMsg();
+
+#if defined(__VERBOSE_DEBUG__)
+ DebugLogNotification(_L("[CNTMODEL] CCntDbNotifyMonitor::RunL"), event);
+#endif
+
+ // Notify all registered observers of the event.
+ for (TInt i = 0 ; i < count ; ++i)
+ {
+ iCurrentProcessedObserver = i;
+ // Ignore any leave so we can notify all registered observers.
+ TRAP_IGNORE(iObserverArray[i]->HandleDatabaseEventL(event));
+ // The call to HandleDatabaseEventL() above may remove or/add observer/observers
+ // so get the count again to cover this scenario. Also we have to update current
+ // loop counter.
+ i = iCurrentProcessedObserver;
+ count = iObserverArray.Count();
+ }
+
+ // Request another event.
+ Start();
+ }
+
+
+/**
+First phase constructor.
+*/
+CCntDbNotifyMonitor::CCntDbNotifyMonitor(RCntModel& aSession)
+ : CCntNotificationMonitor(aSession), iCurrentProcessedObserver(KErrNotFound)
+ {}
+
+
+/**
+Second phase constructor.
+
+@param aSession Client-side session handle for Contacts Model Server.
+*/
+CCntDbNotifyMonitor* CCntDbNotifyMonitor::NewL(RCntModel& aSession)
+ {
+ CCntDbNotifyMonitor* self = new (ELeave) CCntDbNotifyMonitor(aSession);
+ CActiveScheduler::Add(self);
+ return(self);
+ }
+
+
+CCntDbNotifyMonitor::~CCntDbNotifyMonitor()
+ {
+ iObserverArray.Close();
+ }
+
+
+/**
+This method is called to request a Contacts database event from the Server.
+The RunL() method will be called when an event is available (i.e. when the
+Server completes the request.
+*/
+void CCntDbNotifyMonitor::Start()
+ {
+ // Check if a request for a Contacts database event from the Server has
+ // already been issued.
+ if (IsActive())
+ {
+ return;
+ }
+ iStatus=KRequestPending;
+ iSession.StartNotificationTransfer(iStatus, iEventMsg);
+ SetActive();
+ }
+
+
+/**
+Add a Contacts database event observer.
+
+@param aObserver The Contacts database event observer to add.
+*/
+void CCntDbNotifyMonitor::AddObserverL(MContactDbObserver& aObserver)
+ {
+ // Observers can be added from HandleDatabaseEventL() called from CCntDbNotifyMonitor::RunL()
+ // To avoid overcomplicated algorithms for concurent access to handlers array, new observer will
+ // be added always at the end of array. Whilst duplications are not allowed, a search is
+ // needed to check if observer is already added to observers array
+
+ const TInt index = iObserverArray.Find(&aObserver);
+ if( index != KErrNotFound )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+
+ User::LeaveIfError( iObserverArray.Append(&aObserver) );
+
+ // At least one observer now added so start request for Contacts database
+ // event from the Server (if it hasn't already been started i.e. if the AO
+ // is not already active).
+ Start();
+ }
+
+
+/**
+Remove a Contacts database event observer.
+
+@param aObserver The Contacts database event observer to remove.
+*/
+void CCntDbNotifyMonitor::RemoveObserver(const MContactDbObserver& aObserver)
+ {
+ TInt index = iObserverArray.Find(&aObserver);
+ if (index != KErrNotFound)
+ {
+ iObserverArray.Remove(index);
+
+ // Observers can be removed from HandleDatabaseEventL() called from CCntDbNotifyMonitor::RunL()
+ // In order to notify correctly remaining observers, we need to update current processed observer.
+ if( index <= iCurrentProcessedObserver )
+ {
+ --iCurrentProcessedObserver;
+ }
+
+ }
+ // If there are no more observers then cancel the event request in the
+ // Server.
+ if (iObserverArray.Count() == 0)
+ {
+ iSession.EndNotificationTransfer();
+ }
+ }
+
+
+/**
+Get the number of registered observers.
+
+@return The number of registered observers.
+*/
+TInt CCntDbNotifyMonitor::NumberOfListeners() const
+ {
+ return iObserverArray.Count();
+ }
+
+
+TInt CCntDbNotifyMonitor::RunError(TInt /*aError*/)
+ {
+#if defined(__VERBOSE_DEBUG__)
+ TContactDbObserverEvent& event = iEventMsg();
+ DebugLogNotification(_L("[CNTMODEL] CCntDbNotifyMonitor::RunError"), event);
+#endif
+
+ Start();
+
+ return KErrNone;
+ }