diff -r 9f5ae1728557 -r db3f5fa34ec7 messagingfw/biomsgfw/BioWatchers/Src/SmsWatcher.cpp --- /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 +#include +#include +#include + +#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(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& 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& rSocketWatchers) + { + ConstructDbL(); + + TInt pos; + TUid bioMsgID(KNullUid); + CBaseSmsActiveSocketWatcher* socketWatcher = NULL; + + const CArrayFix* 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& 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* socketWatchers = new (ELeave) CArrayPtrFlat(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& 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; + } + } + +