messagingfw/biomsgfw/BioWatchers/Src/SmsWatcher.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/biomsgfw/BioWatchers/Src/SmsWatcher.cpp	Wed Nov 03 22:41:46 2010 +0530
@@ -0,0 +1,370 @@
+// Copyright (c) 2003-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:
+// SmsWatcher.CPP
+//
+
+#include <e32std.h>
+#include <biouids.h>
+#include <c32comm.h>
+#include <smut.h>
+
+#include "SmsWatcher.h"
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
+#include "cwatcher.h"
+#endif
+
+const TInt KAllBioUids = 0;
+
+EXPORT_C CSmsBaseWatcher::CSmsBaseWatcher(RFs& aFs, CWatcherLog& aLog, TInt aPriority)
+: CActive(aPriority), iFs(aFs), iWatcherLog(aLog)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+//
+// Construction/destruction
+
+EXPORT_C void CSmsBaseWatcher::ConstructL()
+	{
+	// The session to the message server is created in the ConstructL because at this 
+	// moment the message server still runs because of the open session in CWatcherLauncherArray
+	// If we would open the session in StartL, the message server will be opened and closed  
+	// several times, which has a negative effect on performance.
+	iSession = CMsvSession::OpenSyncL(*this);
+	
+	User::LeaveIfError(iTimer.CreateLocal());
+	ConstructDbL();
+	CompleteMyself(KErrNone);
+	}
+
+EXPORT_C void CSmsBaseWatcher::StartL()
+	{
+	// put the real construction here
+	iSocketWatchers = new (ELeave) CArrayPtrFlat<CBaseSmsActiveSocketWatcher>(10);
+
+	// Hook into the Bif Change Observer
+	iBifObserver = CBifChangeObserver::NewL(*this, iFs);
+	iBifObserver->Start();
+
+	}
+
+//
+// Construction/destruction
+EXPORT_C CSmsBaseWatcher::~CSmsBaseWatcher()
+	{
+	Cancel();
+	Reset();
+	ResetDb();
+	iTimer.Close();
+	
+	delete iSession;
+	}
+
+EXPORT_C void CSmsBaseWatcher::Reset()
+	{
+	__ASSERT_DEBUG(!IsActive(), PanicWatcher(ESocketWatcherAlreadyActive));
+
+	if (iSocketWatchers)
+		iSocketWatchers->ResetAndDestroy();
+
+	delete iSocketWatchers;
+	iSocketWatchers = NULL;
+
+	delete iBifObserver;
+	iBifObserver = NULL;
+
+	//Do not close iTimer. Leave that for the destructor.
+	}
+
+//
+EXPORT_C void CSmsBaseWatcher::HandleBifChangeL(TBifChangeEvent aEvent, TUid aBioID)
+	{
+	BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Watcher HandleBifChangeL(Event: %d, BioUid: %d)"), aEvent, aBioID.iUid));
+	TInt err = KErrNone;
+
+	switch(aEvent)
+		{
+		case EBifAdded:
+			TRAP(err, AddBifL(aBioID));
+			break;
+		case EBifDeleted:
+			TRAP(err, DeleteBifL(aBioID));
+			break;
+		case EBifChanged:
+			TRAP(err, ReloadBifL(aBioID));
+			break;
+		default:
+			break;
+		} 
+
+	if (err)
+		{
+		BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Watcher HandleBifChangeL(Event: %d, BioUid: %d) error: %d"), aEvent, aBioID.iUid, err));
+		}
+	}
+
+EXPORT_C void CSmsBaseWatcher::RunL()
+	{
+	BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Attempting restart [iStatus=%d]"), iStatus.Int()));
+
+	//Restart the watcher
+	Reset();
+	StartL();
+	}
+
+EXPORT_C void CSmsBaseWatcher::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+EXPORT_C void CSmsBaseWatcher::HandleWatcherComplete(CBaseSmsActiveSocketWatcher& aWatcher, TInt aError)
+	{
+	//Only try to re-start the watcher if it wasn't cancelled.
+	if (!iSocketWatchers || aError == KErrCancel)
+		return;
+
+	TInt count = iSocketWatchers->Count();
+	TInt err = KErrNone;
+	
+	while (count--)
+		{
+		CBaseSmsActiveSocketWatcher* watcher = iSocketWatchers->At(count);
+		
+		if (watcher == &aWatcher)
+			{
+			//Found the same watcher
+			TRAP(err, watcher->SetupL());
+				
+			if (!err)
+				{
+				TRAP(err, watcher->StartL());
+				}
+				
+			if (err)
+				{
+				iSocketWatchers->Delete(count);
+				delete watcher;
+				}
+			
+			break;
+			}
+		}
+	
+	if (err)
+		{
+		//This will call RunL, which will restart the watcher.
+		BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Unable to restart watcher [err=%d, IsActive=%d]"), err, IsActive()));
+		Cancel();
+		iTimer.After(iStatus, KWatcherDelay);
+		SetActive();
+		}
+	}
+
+EXPORT_C void CSmsBaseWatcher::DeleteSocketWatchersWithUidL(TUid aUid)
+	{
+	TInt count = iSocketWatchers->Count();
+
+	while (count--)
+		{
+		CBaseSmsActiveSocketWatcher* socketWatcher = iSocketWatchers->At(count);
+		
+		if (socketWatcher->BioMsgUID() == aUid)
+			{
+			socketWatcher->Cancel();
+			delete socketWatcher;
+			iSocketWatchers->Delete(count);
+			}
+		}
+	}
+
+EXPORT_C void CSmsBaseWatcher::CreateSocketWatchersFromBioDbL(TBioMsgIdType aType)
+	{
+	CreateSocketWatchersFromBioDbL(aType, *iSocketWatchers);
+	}
+
+void CSmsBaseWatcher::CreateSocketWatchersFromBioDbL(TBioMsgIdType aType, CArrayPtrFlat<CBaseSmsActiveSocketWatcher>& rSocketWatchers)
+	{
+	TUid uid;
+	uid.iUid = KAllBioUids;
+	CreateSocketWatchersFromBioDbL(aType, uid, rSocketWatchers);
+	}
+
+EXPORT_C void CSmsBaseWatcher::CreateSocketWatchersFromBioDbL(TBioMsgIdType aType, TUid aBioID)
+	{
+	CreateSocketWatchersFromBioDbL(aType, aBioID, *iSocketWatchers);
+	}
+
+void CSmsBaseWatcher::CreateSocketWatchersFromBioDbL(TBioMsgIdType aType, TUid aUid, CArrayPtrFlat<CBaseSmsActiveSocketWatcher>& rSocketWatchers)
+	{
+	ConstructDbL();
+
+	TInt pos;
+	TUid bioMsgID(KNullUid);
+	CBaseSmsActiveSocketWatcher* socketWatcher = NULL;
+
+	const CArrayFix<TBioMsgId>* bioIDs = iBioDb->BioEntryByTypeLC(CBIODatabase::EStart, aType, pos);
+
+	if (bioIDs)
+		iBioDb->GetBioMsgID(pos, bioMsgID);
+
+	TInt bioDBCount = iBioDb->BIOCount();
+	while( bioIDs != 0 || pos < bioDBCount )
+		{
+		if (aUid.iUid == KAllBioUids || bioMsgID == aUid)
+			{
+			TInt index = 0;
+			if (bioIDs)
+				{
+				index = bioIDs->Count();
+				}
+
+			while (index--)
+				{
+				// Create the Socket Watcher and Add it to the list
+				TBioMsgId msgId = bioIDs->At(index);
+
+				if (msgId.iType == aType && SupportBioMsgId(msgId))
+					{
+					socketWatcher = CreateSocketWatcherLC(bioMsgID, msgId);
+					TInt error = SetupAndAppendL(*socketWatcher, rSocketWatchers);
+
+					if (error)
+						CleanupStack::PopAndDestroy();
+					else
+						CleanupStack::Pop();
+					}
+				}
+			}
+		
+		CleanupStack::PopAndDestroy();	// bioIDs
+		bioIDs = NULL;
+		
+		bioIDs = iBioDb->BioEntryByTypeLC(CBIODatabase::ENext, aType, pos);
+		if (bioIDs)
+			iBioDb->GetBioMsgID(pos, bioMsgID);
+		}
+	}
+
+EXPORT_C void CSmsBaseWatcher::StartSocketWatchersL()
+	{
+	StartSocketWatchersL(*iSocketWatchers);
+	}
+
+void CSmsBaseWatcher::StartSocketWatchersL(const CArrayPtrFlat<CBaseSmsActiveSocketWatcher>& aSocketWatchers)
+	{
+	TInt count = aSocketWatchers.Count();
+
+	//Order Important
+	for (TInt i = 0; i < count; i++)
+		{
+		CBaseSmsActiveSocketWatcher* socketWatcher = aSocketWatchers[i];
+		socketWatcher->SetObserver(this);
+		socketWatcher->StartL();
+		}
+	}
+
+EXPORT_C void CSmsBaseWatcher::DeleteBifL(TUid aBioID)
+	{
+	DeleteSocketWatchersWithUidL(aBioID);
+	}
+
+EXPORT_C void CSmsBaseWatcher::ReloadBifL(TUid aBioID)
+	{
+	DeleteBifL(aBioID);
+	AddBifL(aBioID);
+	}
+
+EXPORT_C void CSmsBaseWatcher::AddBifWithTypeL(TBioMsgIdType aType, TUid aBioID)
+	{
+	CArrayPtrFlat<CBaseSmsActiveSocketWatcher>* socketWatchers = new (ELeave) CArrayPtrFlat<CBaseSmsActiveSocketWatcher>(1);
+	CleanupStack::PushL(socketWatchers);
+
+	CreateSocketWatchersFromBioDbL(aType, aBioID, *socketWatchers);
+	StartSocketWatchersL(*socketWatchers);
+
+	TInt count = socketWatchers->Count();
+	while (count--)
+		{
+		iSocketWatchers->AppendL(socketWatchers->At(count));
+		}
+
+	CleanupStack::PopAndDestroy(); //socketWatchers
+	}
+
+EXPORT_C TInt CSmsBaseWatcher::SetupAndAppendL(CBaseSmsActiveSocketWatcher& aSocketWatcher, CArrayPtrFlat<CBaseSmsActiveSocketWatcher>& rSocketWatchers)
+	{
+	TRAPD(error, aSocketWatcher.SetupL());
+
+	if (!error)
+		{
+		rSocketWatchers.AppendL(&aSocketWatcher);
+		}
+	else 
+		{
+		BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Watcher setup error - %d"), error));
+
+		if (error != KErrAlreadyExists && error != KErrNotFound)
+			User::Leave(error);
+		else
+			BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: Ignoring watcher error - Config problem?")));
+		}
+
+	return error;
+	}
+
+void CSmsBaseWatcher::ConstructDbL()
+	{
+	if (iBioDb == NULL)
+		iBioDb = CBIODatabase::NewL(iFs);
+	}
+
+EXPORT_C void CSmsBaseWatcher::ResetDb()
+	{
+	delete iBioDb;
+	iBioDb = NULL;
+	}
+
+EXPORT_C void CSmsBaseWatcher::CompleteMyself(TInt aError)
+	{
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, aError);
+	SetActive();
+	}
+
+EXPORT_C TInt CSmsBaseWatcher::RunError(TInt aError)
+	{
+	BIOWATCHERLOG(iWatcherLog.Printf(_L8("Bio: RunL left with %d. Restarting in %d sec"), aError, KWatcherDelay / 1000000));
+
+	iTimer.After(iStatus, KWatcherDelay);
+	SetActive();
+
+	return KErrNone;
+	}
+
+EXPORT_C void CSmsBaseWatcher::GetBioServiceId(CMsvSession& aSession, TMsvId& aBioServiceId, TMsvId& aSmsServiceId)
+	{
+	TInt err = KErrNone;
+	TRAP(err, TSmsUtilities::ServiceIdL(aSession, aBioServiceId, KUidBIOMessageTypeMtm));
+	if (err == KErrNotFound)
+		{
+		aBioServiceId = KMsvLocalServiceIndexEntryId;
+		}
+	TRAP(err, TSmsUtilities::ServiceIdL(aSession, aSmsServiceId));
+	if (err == KErrNotFound)
+		{
+		aSmsServiceId = KMsvLocalServiceIndexEntryId;
+		}
+	}
+
+