diff -r 000000000000 -r 2f259fa3e83a applicationinterworkingfw/ServiceHandler/src/AiwServiceHandlerImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applicationinterworkingfw/ServiceHandler/src/AiwServiceHandlerImpl.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,1853 @@ +/* +* Copyright (c) 2003-2005 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: Implements API for consumer application to access Application +* Interworking Framework. +* +*/ + + + + +#include +#include +#include +#include "AiwMenuBinding.h" +#include "AiwServiceHandlerImpl.h" +#include "AiwMenu.h" +#include "AiwUids.hrh" +#include "AiwCommon.hrh" +#include "AiwMenuSlot.hrh" +#include "AiwEcomMonitor.h" +#include "AiwTlsData.h" +#include "data_caging_path_literals.hrh" + +// CONSTANTS +// Max number of empty menu resource slots. +const TInt KMaxMenuResources = 16; + +// This value tells how many times consumer can call InitializeMenuPaneL() without +// closing the Options-menu. +const TInt KMaxPaneIds = KMaxMenuResources; + +// The range reserved for individual menu pane. +const TInt KIndividualMenuPaneIdRange = 10000; + +// The whole range that is reserved to all menu panes. Currently value is 170 000. +const TInt KMenuPaneCommandRange = (KMaxMenuResources + 1) * KIndividualMenuPaneIdRange; + +_LIT(KAiwResourceFile, "AiwServiceHandler.rSC"); +_LIT(KAiwZDrive, "z:"); + +const TInt KMaxMenuTitleSize = 100; + +// Command id space reserved for single placeholder. +const TInt KPlaceholderCmdIdRange = 200; + +void Cleanup(TAny* aAny); +void InterestCleanup(TAny* aAny); +void IntArrayCleanup(TAny* aAny); +void FilteredCleanup(TAny* aAny); + + +// +// AiwServiceHandler +// + +CAiwServiceHandlerImpl* CAiwServiceHandlerImpl::NewL() + { + CAiwServiceHandlerImpl* handler = new (ELeave) CAiwServiceHandlerImpl(); + CleanupStack::PushL( handler ); + handler->ConstructL(); + CleanupStack::Pop(); // handler + return handler; + } + + + +CAiwServiceHandlerImpl::CAiwServiceHandlerImpl() + { + // Nothing to do here. + } + + + +void CAiwServiceHandlerImpl::ConstructL() + { + TFileName resFile; + + TCallBack callBack(SynchronizeCallBack, this); + iEcomMonitor = CAiwEcomMonitor::NewL(callBack); + + resFile.Copy(KAiwZDrive); + resFile.Append(KDC_RESOURCE_FILES_DIR); + resFile.Append(KAiwResourceFile); + + iCoeEnv = CCoeEnv::Static(); + + // A Service Handler instance can be created also when CCoeEnv is not + // available (e.g. from server applications). In this case, the methods + // needing CCoeEnv/CEikonEnv will leave with KErrNotSupported. + if(iCoeEnv) + { + iResourceOffset = iCoeEnv->AddResourceFileL(resFile); + } + + // CAiwTlsData has a reference count so each OpenL call + // must have a matching Close call (done in destructor). + // OpenL is called only here, the TLS data object can be + // referenced by calling CAiwTlsData::Instance(). + CAiwTlsData* data = CAiwTlsData::OpenL(); + iTlsDataOpened = ETrue; + + // CEikMenuPane informs all menu launch observers + // when an options menu is launched. + data->AddMenuLaunchObserverL( this ); + } + + + +CAiwServiceHandlerImpl::~CAiwServiceHandlerImpl() + { + if (iResourceOffset && iCoeEnv) + { + iCoeEnv->DeleteResourceFile(iResourceOffset); + } + Reset(); + + delete iEcomMonitor; + + if ( iTlsDataOpened ) + { + CAiwTlsData* data = CAiwTlsData::Instance(); + data->RemoveMenuLaunchObserver( this ); + CAiwTlsData::Close(); + } + } + + + +void CAiwServiceHandlerImpl::Reset() + { + iInterestList.ResetAndDestroy(); + iMenuBindings.ResetAndDestroy(); + iBaseBindings.ResetAndDestroy(); + iProviders.ResetAndDestroy(); + + iLastInitialized.Reset(); + + iMenuPanes.ResetAndDestroy(); + + delete iInParams; + iInParams = NULL; + delete iOutParams; + iOutParams = NULL; + } + + + +void CAiwServiceHandlerImpl::ListProvidersForCriteriaL(RArray& aResult, + CAiwCriteriaItem& aItem) + { + TInt i; + + for (i = 0; i < iProviders.Count(); i++) + { + if (iProviders[i]->HasCriteria(aItem)) + { + User::LeaveIfError(aResult.Append(iProviders[i]->ImplementationUid().iUid)); + } + } + } + + + +TInt CAiwServiceHandlerImpl::NbrOfProviders(const CAiwCriteriaItem* aCriteria) + { + if(!aCriteria) + { + return 0; + } + + TInt i, j; + + for (i = 0; i < iBaseBindings.Count(); i++) + { + for (j = 0; j < iBaseBindings[i]->Interest().Count(); j++) + { + if ((*iBaseBindings[i]->Interest()[j]) == (*aCriteria)) + { + return iBaseBindings[i]->NumberOfProviders(); + } + } + } + + for (i = 0; i < iMenuBindings.Count(); i++) + { + for (j = 0; j < iMenuBindings[i]->Interest().Count(); j++) + { + if ((*iMenuBindings[i]->Interest()[j]) == (*aCriteria)) + { + return iMenuBindings[i]->NumberOfProviders(); + } + } + } + + return 0; + } + + + +void CAiwServiceHandlerImpl::AttachL(TInt aInterestResourceId) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + RCriteriaArray interest, filtered; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) ); + + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId); + ReadInterestListL(reader, interest); + CleanupStack::PopAndDestroy(); // reader + + FilterInterestListL(interest, filtered); + + DoAttachL(filtered); + + filtered.Reset(); + + CleanupStack::Pop(); // filtered + CleanupStack::Pop(); // interest + } + + + +void CAiwServiceHandlerImpl::AttachL(const RCriteriaArray& aInterest) + { + RCriteriaArray interest, filtered; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) ); + + for(TInt i = 0; i < aInterest.Count(); i++) + { + CAiwCriteriaItem* item = CAiwCriteriaItem::NewLC(); + + item->SetId( aInterest[i]->Id() ); + item->SetServiceCmd( aInterest[i]->ServiceCmd() ); + item->SetContentTypeL( aInterest[i]->ContentType() ); + item->SetServiceClass( aInterest[i]->ServiceClass() ); + item->SetOptions( aInterest[i]->Options() ); + item->SetDefaultProvider( (aInterest[i]->DefaultProvider()).iUid ); + item->SetMaxProviders( aInterest[i]->MaxProviders() ); + + User::LeaveIfError(interest.Append(item)); + CleanupStack::Pop(item); + } + + FilterInterestListL(interest, filtered); + + DoAttachL(filtered); + + filtered.Reset(); + + CleanupStack::Pop(); // filtered + CleanupStack::Pop(); // interest + } + + + +void CAiwServiceHandlerImpl::DoAttachL(const RCriteriaArray& aInterest) + { + CAiwBinding* bind; + for (TInt i = 0; i < aInterest.Count(); i++) + { + bind = CAiwBinding::NewLC(); + + if (ResolveProvidersL(bind, aInterest[i])) + { + User::LeaveIfError(iBaseBindings.Append( bind )); + CleanupStack::Pop(); // bind + bind->AddCriteriaL(aInterest[i]); + + // Initialise providers. + for (TInt k = 0; k < bind->NumberOfProviders(); k++) + { + // Trap the initialisation. If not done, a leaving provider + // could prevent the initialisation of other providers. + TRAPD(err, bind->BaseProvider(k)->InitialiseL(*this, bind->Interest())); + if(err) + { +#ifdef _DEBUG + RDebug::Print(_L("AIW PROVIDER ERROR: CAiwServiceIfBase::InitialiseL() failed, leave code:%d"), err); +#endif + } + } + } + else + { + CleanupStack::PopAndDestroy(); // bind + } + } + } + + +void CAiwServiceHandlerImpl::GetInterest(RCriteriaArray& aInterest) + { + for (TInt i = 0; i < iInterestList.Count(); i++) + { + if (aInterest.Append(iInterestList[i]) != KErrNone) + { + return; + } + } + } + + + +void CAiwServiceHandlerImpl::DetachL(const RCriteriaArray& aInterest) + { + // First, remove relevant criteria items from relevat base bindings. + for (TInt i = 0; i < aInterest.Count(); i++) + { + for (TInt j = 0; j < iBaseBindings.Count(); j++) + { + TInt index = iBaseBindings[j]->HasCriteriaItem(*aInterest[i]); + if (index != KErrNotFound) + { + iBaseBindings[j]->RemoveCriteria(index); + } + } + } + + // Second pass removes empty bindings. + for (TInt i = 0; i < iBaseBindings.Count(); i++) + { + if (iBaseBindings[i]->Interest().Count() == 0) + { + delete iBaseBindings[i]; + iBaseBindings.Remove(i); + i--; + } + } + + // Then check if there were left obselete criteria items and remove them. + RemoveObsoleteCriteriaItems(); + + // Finally check if there were left obselete providers and remove them. + RemoveObsoleteProviders(); + } + + + +void CAiwServiceHandlerImpl::DetachL(TInt aInterestResourceId) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + RCriteriaArray interest; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId); + ReadInterestListL(reader, interest); + CleanupStack::PopAndDestroy(); // reader + + DetachL( interest ); + + interest.ResetAndDestroy(); + CleanupStack::Pop(); // interest + } + + +const CAiwCriteriaItem* CAiwServiceHandlerImpl::GetCriteria(TInt aId) + { + for (TInt i = 0; i < iInterestList.Count(); i++) + { + if (iInterestList[i]->Id() == aId) + { + return iInterestList[i]; + } + } + + return NULL; + } + +TInt CAiwServiceHandlerImpl::NumAlreadyInitializedPaneIdsL() const + { + TInt ret = 0; + TInt paneIds[KMaxPaneIds] = {0}; + TBool found = EFalse; + + for (TInt i = 0; i < iLastInitialized.Count(); i++) + { + found = EFalse; + + for (TInt j = 0; j < ret; j++) + { + if (iLastInitialized[i]->MenuResourceId() == paneIds[j]) + { + found = ETrue; + break; + } + } + + if (!found) + { + // Create new item. + if (ret >= KMaxPaneIds) + { +#ifdef _DEBUG + RDebug::Print(_L("ERROR: OVERFLOW in CAiwServiceHandlerImpl::NumAlreadyInitializedPaneIdsL()")); +#endif + User::Leave(KErrOverflow); + } + paneIds[ret] = iLastInitialized[i]->MenuResourceId(); + ret++; + } + } + return ret; + } + +void CAiwServiceHandlerImpl::InitializeMenuPaneL( + CEikMenuPane& aMenuPane, + TInt aMenuResourceId, + TInt aBaseMenuCmdId, + const CAiwGenericParamList& aInParamList) + { + InitializeMenuPaneL(aMenuPane, aMenuResourceId, aBaseMenuCmdId, + aInParamList, EFalse, EFalse); + } + +void CAiwServiceHandlerImpl::InitializeMenuPaneL( + CEikMenuPane& aMenuPane, + TInt aMenuResourceId, + TInt aBaseMenuCmdId, + const CAiwGenericParamList& aInParamList, + TBool aUseSubmenuTextsIfAvailable) + { + InitializeMenuPaneL(aMenuPane, aMenuResourceId, aBaseMenuCmdId, aInParamList, aUseSubmenuTextsIfAvailable, EFalse); + } + + +void CAiwServiceHandlerImpl::InitializeMenuPaneL( + CEikMenuPane& aMenuPane, + TInt aMenuResourceId, + TInt aBaseMenuCmdId, + const CAiwGenericParamList& aInParamList, + TBool aUseSubmenuTextsIfAvailable, + TBool aSetAsItemSpecific) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + if (!iMenuBindings.Count()) + { + // Either no menu is attached to interest or menu was attached but + // it didn't contain any placeholders for criteria items. So + // nothing to do, get out. + return; + } + + TInt index; + TInt slotcmd; + TBuf subTitle; + TBool titleLocked; + TInt paneOffset = NumAlreadyInitializedPaneIdsL() * KIndividualMenuPaneIdRange; + + iSubmenuCmd = aBaseMenuCmdId + KMenuPaneCommandRange; + slotcmd = SlotItemCmd(aMenuPane); + if (slotcmd >= 0) + { + // aMenuPane is aiw submenu. At this point it is empty and we must + // copy provider menu items to it. + CAiwMenuPane* aiwPane = MenuPaneForSlotCmd(slotcmd); + if (aiwPane) + { + CopyMenuItemsL(aiwPane, aMenuPane, 0, ETrue, aSetAsItemSpecific); + aMenuPane.DeleteMenuItem(slotcmd); + iSubmenu = aiwPane; + } + } + else + { + iSubmenu = NULL; + + const TInt bindcount = iMenuBindings.Count(); + for (TInt i = 0; i < bindcount; i++) + { + if ((iMenuBindings[i]->MenuId() == aMenuResourceId) && + (aMenuPane.MenuItemExists(iMenuBindings[i]->MenuCmd(), index))) + { + CAiwMenuPane* aiwPane = iMenuBindings[i]->MenuPane(); + TInt menuResourceId = -1; + if(aiwPane) + { + // An AIW menu pane already exists (this means that a normal + // non-AIW submenu with AIW items has been opened more than once). + // In this case we use the existing resource slot id. + menuResourceId = aiwPane->ResourceSlotId(); + paneOffset = aiwPane->PaneOffset(); + DeleteAiwMenuPane(aiwPane); + aiwPane = NULL; + } + aiwPane = CreateEmptyAiwMenuPaneL(aBaseMenuCmdId, menuResourceId); + CleanupStack::PushL(aiwPane); + aiwPane->SetPaneOffset(paneOffset); + paneOffset += KPlaceholderCmdIdRange; + iMenuBindings[i]->SetMenuPane(aiwPane); + + // Clean previous service commands from list. + CAiwGenericParamList& list = const_cast(aInParamList); + while (list.Remove(EGenericParamServiceCommand)) + { + // Intentionally left empty. + } + + // Add service commands for current placeholder. + const TInt icount = iMenuBindings[i]->Interest().Count(); + for (TInt k = 0; k < icount; k++) + { + list.AppendL(TAiwGenericParam(EGenericParamServiceCommand, + TAiwVariant(iMenuBindings[i]->Interest()[k]->ServiceCmd()))); + } + + // Loop from last entry to first entry always inserting to same index. + // Default provider is the first item in list, so if there is a default + // provider defined, it will be the first one to appear in menus. + for (TInt j = iMenuBindings[i]->NumberOfProviders() - 1; j >= 0; j--) + { + aiwPane->SetInitializingOwner(iMenuBindings[i]->MenuProvider(j)); + iMenuBindings[i]->MenuProvider(j)->InitializeMenuPaneHookL(aiwPane, + 0, 0, aInParamList); + } + + GetSubmenuTitle(aiwPane->MenuPane(), subTitle); + + TAiwPlaceholderType phtype = PlaceholderType(aMenuPane, + iMenuBindings[i]->MenuCmd(), titleLocked); + + if ((phtype == EAiwPlaceholderCascade) || + (phtype == EAiwPlaceholderIntelligentCascade)) + { + if (aiwPane->MenuPane().NumberOfItemsInPane() == 1) + { + // Remove placeholder item. + aMenuPane.DeleteMenuItem(iMenuBindings[i]->MenuCmd()); + CleanupStack::PopAndDestroy(); // aiwPane + continue; + } + else if ((aiwPane->MenuPane().NumberOfItemsInPane() == 2) && + (phtype == EAiwPlaceholderIntelligentCascade)) + { + UnCascadeL(aMenuPane, iMenuBindings[i]->MenuCmd(), *aiwPane, aSetAsItemSpecific); + User::LeaveIfError(iLastInitialized.Append(aiwPane)); + } + else + { + if (titleLocked) + { + subTitle.Zero(); + } + ConvertPlaceholderL(aMenuPane, iMenuBindings[i]->MenuCmd(), *aiwPane, + subTitle, aSetAsItemSpecific); + } + } + else + { + // Remove placeholder item. + aMenuPane.DeleteMenuItem(iMenuBindings[i]->MenuCmd()); + + // Copy menu items to actual menu pane + CopyMenuItemsL(aiwPane, aMenuPane, index, aUseSubmenuTextsIfAvailable, aSetAsItemSpecific); + + User::LeaveIfError(iLastInitialized.Append(aiwPane)); + } + aiwPane->SetMenuResourceId(aMenuResourceId); + User::LeaveIfError(iMenuPanes.Append(aiwPane)); + CleanupStack::Pop(); // aiwPane + } + } + } + } + + +TInt CAiwServiceHandlerImpl::ServiceCmdByMenuCmd(TInt aMenuCmdId) const + { + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if ((IsInLastInitialized(iMenuBindings[i]->MenuPane())) && + (iMenuBindings[i]->MenuPane()->IsCmdInRange(KPlaceholderCmdIdRange, aMenuCmdId))) + { + return iMenuBindings[i]->MenuPane()->ServiceCmdId(aMenuCmdId); + } + } + + return 0; + } + + + +void CAiwServiceHandlerImpl::ExecuteMenuCmdL( + TInt aMenuCmdId, + const CAiwGenericParamList& aInParamList, + CAiwGenericParamList& aOutParamList, + TUint aCmdOptions, + MAiwNotifyCallback* aCallback) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + if (!iMenuBindings.Count()) + { + return; + } + + // Handle real menu providers. + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + CAiwMenuPane* menuPane = iMenuBindings[i]->MenuPane(); + + if (IsInLastInitialized(menuPane)) + { + for (TInt j = 0; j < iMenuBindings[i]->NumberOfProviders(); j++) + { + if ((menuPane->IsCmdInRange(KPlaceholderCmdIdRange, aMenuCmdId)) && + (menuPane->CommandOwner(aMenuCmdId) == iMenuBindings[i]->MenuProvider(j))) + { + iMenuBindings[i]->MenuProvider(j)->HandleMenuCmdHookL( + menuPane, + aMenuCmdId, + aInParamList, + aOutParamList, + aCmdOptions, + aCallback); + return; + } + } + } + } + } + + + +void CAiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, TInt aInterestResourceId) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + RCriteriaArray interest, filtered; + TResourceReader reader; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) ); + iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId); + ReadInterestListL(reader, interest); + CleanupStack::PopAndDestroy(); // reader + FilterInterestListL(interest, filtered); + + iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId); + DoAttachMenuL(reader, aMenuResourceId, filtered); + filtered.Reset(); + CleanupStack::PopAndDestroy(); // reader + CleanupStack::Pop(); // filtered + CleanupStack::Pop(); // interest + } + + + +void CAiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, TResourceReader& aReader) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + RCriteriaArray interest, filtered; + TResourceReader reader; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) ); + ReadInterestListL(aReader, interest); + FilterInterestListL(interest, filtered); + + iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId); + DoAttachMenuL(reader, aMenuResourceId, filtered); + filtered.Reset(); + CleanupStack::PopAndDestroy(); // reader + CleanupStack::Pop(); // filtered + CleanupStack::Pop(); // interest + } + + +void CAiwServiceHandlerImpl::AttachMenuL(TInt aMenuResourceId, const RCriteriaArray& aInterest) + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + User::Leave(KErrNotSupported); + } + + RCriteriaArray interest, filtered; + TResourceReader reader; + + CleanupStack::PushL( TCleanupItem( InterestCleanup, &interest ) ); + CleanupStack::PushL( TCleanupItem( FilteredCleanup, &filtered ) ); + + for(TInt i = 0; i < aInterest.Count(); i++) + { + CAiwCriteriaItem* item = CAiwCriteriaItem::NewLC(); + + item->SetId( aInterest[i]->Id() ); + item->SetServiceCmd( aInterest[i]->ServiceCmd() ); + item->SetContentTypeL( aInterest[i]->ContentType() ); + item->SetServiceClass( aInterest[i]->ServiceClass() ); + item->SetOptions( aInterest[i]->Options() ); + item->SetDefaultProvider( (aInterest[i]->DefaultProvider()).iUid ); + item->SetMaxProviders( aInterest[i]->MaxProviders() ); + + User::LeaveIfError(interest.Append(item)); + CleanupStack::Pop(item); + } + + FilterInterestListL(interest, filtered); + + iCoeEnv->CreateResourceReaderLC(reader, aMenuResourceId); + DoAttachMenuL(reader, aMenuResourceId, filtered); + filtered.Reset(); + CleanupStack::PopAndDestroy(); // reader + CleanupStack::Pop(); // filtered + CleanupStack::Pop(); // interest + } + + +void CAiwServiceHandlerImpl::DoAttachMenuL(TResourceReader& aReader, TInt aMenuId, + RCriteriaArray& aInterest) + { + TInt menuCmd; + TInt count = aReader.ReadInt16(); + TBool bound; + + for (TInt i = 0; i < count; i++) + { + menuCmd = aReader.ReadInt32(); + CAiwMenuBinding* bind = NULL; + bound = EFalse; + + for (TInt j = 0; j < aInterest.Count(); j++) + { + if (aInterest[j]->Id() == menuCmd) + { + if (!bind) + { + bind = AlreadyBound(aMenuId, menuCmd, i); + if (!bind) + { + bind = CAiwMenuBinding::NewLC(i, aMenuId); + bind->SetMenuCmd( menuCmd ); + } + else + { + bound = ETrue; + } + } + + if (bind->HasCriteriaItem(*(aInterest[j])) == KErrNotFound) + { + ResolveProvidersL(bind, aInterest[j]); + bind->AddCriteriaL(aInterest[j]); + } + } + } + + // Initialise providers. + if (bind) + { + for (TInt k = 0; k < bind->NumberOfProviders(); k++) + { + TRAPD(err, bind->MenuProvider(k)->InitialiseL(*this, bind->Interest())); + if(err) + { +#ifdef _DEBUG + RDebug::Print(_L("AIW PROVIDER ERROR: CAiwServiceIfMenu::InitialiseL() failed, leave code:%d"), err); +#endif + // The provider failed to initialise. + // Remove the failed provider from this menu binding. + CAiwServiceIfMenu* provider = bind->MenuProvider(k); + TInt implUid = provider->ImplementationUid().iUid; + bind->RemoveProvider(implUid); + + // Remove the failed provider also from other menu bindings. + for (TInt m = 0; m < iMenuBindings.Count(); m++) + { + iMenuBindings[m]->RemoveProvider(implUid); + } + + // Then remove provider from the owner list and delete it. + for (TInt m = 0; m < iProviders.Count(); m++) + { + if (iProviders[m]->ImplementationUid().iUid == implUid) + { + delete iProviders[m]; + iProviders.Remove(m); + m--; + } + } + } + } + if (!bound) + { + User::LeaveIfError(iMenuBindings.Append( bind )); + CleanupStack::Pop(); // bind + } + } + SkipMenuFields(aReader); // Jump to next menu item + } + } + + +void CAiwServiceHandlerImpl::ReadInterestL(RCriteriaArray& aInterest, TInt aInterestResourceId) + { + CleanupStack::PushL( TCleanupItem( InterestCleanup, &aInterest ) ); + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC(reader, aInterestResourceId); + ReadInterestListL(reader, aInterest); + CleanupStack::PopAndDestroy(); // reader + CleanupStack::Pop(&aInterest); + } + + +void CAiwServiceHandlerImpl::DetachMenu(TInt aMenuResourceId, TInt aInterestResourceId) + { + // If interest resource id is null, then detach all items in the given menu. + if (!aInterestResourceId) + { + DoDetachMenu(aMenuResourceId); + } + else + { + // CCoeEnv/CEikonEnv needs to be accessible. + if(!iCoeEnv) + { + // We cannot leave because this is a non-leaving method. + return; + } + + RCriteriaArray interest; + TRAPD(err, ReadInterestL(interest, aInterestResourceId)); + if (err) + { + return; + } + + DoDetachMenu(aMenuResourceId, interest); + + interest.ResetAndDestroy(); + } + } + + +void CAiwServiceHandlerImpl::DoDetachMenu(TInt aMenuResourceId) + { + // First, delete the relevant menu bindings. + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->MenuId() == aMenuResourceId) + { + delete iMenuBindings[i]; + iMenuBindings.Remove(i); + i--; + } + } + + // Then check if there were left obselete criteria items and remove them. + RemoveObsoleteCriteriaItems(); + + // Finally check if there were left obselete providers and remove them. + RemoveObsoleteProviders(); + } + + +void CAiwServiceHandlerImpl::DoDetachMenu(TInt aMenuResourceId, RCriteriaArray& aInterest) + { + // First, remove relevant criteria items from relevant menu bindings. + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->MenuId() == aMenuResourceId) + { + for (TInt j = 0; j < aInterest.Count(); j++) + { + TInt index = iMenuBindings[i]->HasCriteriaItem(*aInterest[j]); + if (index != KErrNotFound) + { + iMenuBindings[i]->RemoveCriteria(index); + } + } + } + } + + // Second pass removes empty bindings. + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->Interest().Count() == 0) + { + delete iMenuBindings[i]; + iMenuBindings.Remove(i); + i--; + } + } + + // Then check if there were left obselete criteria items and remove them. + RemoveObsoleteCriteriaItems(); + + // Finally check if there were left obselete providers and remove them. + RemoveObsoleteProviders(); + } + + +void CAiwServiceHandlerImpl::RemoveObsoleteCriteriaItems() + { + for (TInt i = 0; i < iInterestList.Count(); i++) + { + CAiwCriteriaItem* criteria = iInterestList[i]; + TBool found = EFalse; + + // Loop through base bindings. + for (TInt j = 0; j < iBaseBindings.Count(); j++) + { + if (iBaseBindings[j]->HasCriteriaItem(*criteria) != KErrNotFound) + { + found = ETrue; + break; + } + } + + // If still not found, loop through menu bindings. + if (!found) + { + for (TInt j = 0; j < iMenuBindings.Count(); j++) + { + if (iMenuBindings[j]->HasCriteriaItem(*criteria) != KErrNotFound) + { + found = ETrue; + break; + } + } + } + + // Criteria item can be deleted if it was not found. + if (!found) + { + delete iInterestList[i]; + iInterestList.Remove(i); + i--; + } + } + } + + +void CAiwServiceHandlerImpl::RemoveObsoleteProviders() + { + for (TInt i = 0; i < iProviders.Count(); i++) + { + CAiwServiceIfBase* provider = iProviders[i]; + TBool found = EFalse; + + // Loop through base bindings. + for (TInt j = 0; j < iBaseBindings.Count(); j++) + { + if (iBaseBindings[j]->HasProvider(provider)) + { + found = ETrue; + break; + } + } + + // If still not found, loop through menu bindings. + if (!found) + { + for (TInt j = 0; j < iMenuBindings.Count(); j++) + { + if (iMenuBindings[j]->HasProvider(provider)) + { + found = ETrue; + break; + } + } + } + + // Criteria item can be deleted if it was not found. + if (!found) + { + delete iProviders[i]; + iProviders.Remove(i); + i--; + } + } + } + + +TBool CAiwServiceHandlerImpl::IsSubMenuEmpty(TInt aSubMenuId) + { + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->MenuId() == aSubMenuId) + { + if (iMenuBindings[i]->NumberOfProviders() > 0) + { + return EFalse; + } + + return ETrue; + } + } + + return EFalse; + } + + + + +CAiwMenuBinding* CAiwServiceHandlerImpl::AlreadyBound(TInt aMenuId, TInt aMenuCmd, + TInt aMenuItemIndex) const + { + for (TInt i = 0; i < iMenuBindings.Count(); i++) + { + if ((iMenuBindings[i]->MenuId() == aMenuId) && + (iMenuBindings[i]->MenuCmd() == aMenuCmd) && + (iMenuBindings[i]->MenuItemIndex() == aMenuItemIndex)) + { + return iMenuBindings[i]; + } + } + + return NULL; + } + + +void CAiwServiceHandlerImpl::ExecuteServiceCmdL( + const TInt& aCmdId, + const CAiwGenericParamList& aInParamList, + CAiwGenericParamList& aOutParamList, + TUint aCmdOptions, + MAiwNotifyCallback* aCallback) + { + for (TInt i = 0; i < iBaseBindings.Count(); i++) + { + if(iBaseBindings[i]->HasServiceCmd(aCmdId)) + { + for (TInt j = 0; j < iBaseBindings[i]->NumberOfProviders(); j++) + { + iBaseBindings[i]->BaseProvider(j)->HandleServiceCmdL( + aCmdId, + aInParamList, + aOutParamList, + aCmdOptions, + aCallback); + } + } + } + } + + + +void CAiwServiceHandlerImpl::ReadInterestListL(TResourceReader& aReader, + RPointerArray& aResult) + { + const TInt count = aReader.ReadInt16(); + for (TInt ii = 0; ii < count; ++ii) + { + CAiwCriteriaItem* item = CAiwCriteriaItem::NewLC(); + item->ReadFromResoureL( aReader ); + User::LeaveIfError(aResult.Append(item)); + CleanupStack::Pop(); // item + } + } + + +TInt CAiwServiceHandlerImpl::ResolveProvidersL(CAiwBinding* aBinding, CAiwCriteriaItem* aItem) + { + RImplInfoPtrArray infoArray; + TInt result = 0; + + CleanupStack::PushL( TCleanupItem( Cleanup, &infoArray ) ); + + iEcomMonitor->ListImplemetationsL(infoArray, aItem); + + FilterInfoArray(infoArray, aItem); + + // First resolve for providers already in memory. + TInt i; + for (i = 0; i < iProviders.Count(); i++) + { + if (iProviders[i]->Match(aItem)) + { + aBinding->AddProviderL((CAiwServiceIfBase*)iProviders[i], + iProviders[i]->ImplementationUid() == aItem->DefaultProvider()); + result++; + } + } + + // If cached providers were found, then it means that all the matching + // providers must be already in memory. No need to query from ECom framework. + if (!result) + { + for (i = 0; i < infoArray.Count(); i++) + { + if ((aItem->Options() & AIW_OPTIONS_ROM_ONLY) && (infoArray[i]->RomBased() == EFalse)) + { + continue; + } + + CAiwServiceIfBase* iface = NULL; + TRAP_IGNORE( iface = iEcomMonitor->CreateImplementationL( + infoArray[i]->ImplementationUid()) ); + + if (iface) + { + if (!IsCached(iface)) + { + CleanupStack::PushL(iface); + result++; + iface->AddCriteria(aItem); + User::LeaveIfError(iProviders.Append( iface )); + CleanupStack::Pop(iface); + + aBinding->AddProviderL(iface, + infoArray[i]->ImplementationUid() == aItem->DefaultProvider()); + } + else + { + delete iface; + iface = NULL; + } + } + } + } + + CleanupStack::PopAndDestroy(); // infoArray + + return result; + } + + + +void CAiwServiceHandlerImpl::FilterInfoArray(RImplInfoPtrArray& aArray, CAiwCriteriaItem* aItem) + { + if (aItem->MaxProviders() <= 0) + { + aArray.ResetAndDestroy(); + } + else + { + while (aArray.Count() > aItem->MaxProviders()) + { + // Skip default provider. + if (aArray[0]->ImplementationUid() == aItem->DefaultProvider()) + { + delete aArray[1]; + aArray.Remove(1); + } + else + { + delete aArray[0]; + aArray.Remove(0); + } + } + } + } + + + +TBool CAiwServiceHandlerImpl::IsCached(CAiwServiceIfBase* /*aProvider*/) + { + return EFalse; + } + + +CAiwGenericParamList& CAiwServiceHandlerImpl::InParamListL() + { + if (!iInParams) + { + iInParams = CAiwGenericParamList::NewL(); + } + iInParams->Reset(); + return *iInParams; + } + + + +CAiwGenericParamList& CAiwServiceHandlerImpl::OutParamListL() + { + if (!iOutParams) + { + iOutParams = CAiwGenericParamList::NewL(); + } + iOutParams->Reset(); + return *iOutParams; + } + + + +TBool CAiwServiceHandlerImpl::IsInLastInitialized(CAiwMenuPane* aiwPane) const + { + if (aiwPane) + { + if (iSubmenu == aiwPane) + { + return ETrue; + } + + for (TInt i = 0; i < iLastInitialized.Count(); i++) + { + if (iLastInitialized[i] == aiwPane) + { + return ETrue; + } + } + } + + return EFalse; + } + + +TInt CAiwServiceHandlerImpl::HandleNotifyL( + TInt /*aCmdId*/, + TInt /*aEventId*/, + CAiwGenericParamList& /*aEventParamList*/, + const CAiwGenericParamList& /*aInParamList*/) + { + return KErrNone; + } + + +// CEikMenuPane::ConstructFromresourceL is defined as 'protected' so +// we have to use a wrapper class for accessing it. +class CAiwMenuResource : public CEikMenuPane + { + public: + CAiwMenuResource() : CEikMenuPane(NULL) {} + CAiwMenuResource(MEikMenuObserver* aObserver) : CEikMenuPane(aObserver) {} + + void CreateL(TResourceReader& aReader) + { + ConstructFromResourceL(aReader); + } + }; + + +CAiwMenuPane* CAiwServiceHandlerImpl::CreateEmptyAiwMenuPaneL(TInt aBaseMenuCmdId, + TInt aResourceId) + { + CAiwMenuPane* result = NULL; + TResourceReader reader; + + TInt id; + if(aResourceId >= 0) + { + // Use existing id. + id = aResourceId; + } + else + { + // Create new id. + id = ResourceIdForNextFreeSlot(); + if (id < 0) + { + User::Leave(KErrOverflow); + } + } + iCoeEnv->CreateResourceReaderLC(reader, id); + + CAiwMenuResource* pane = new (ELeave) CAiwMenuResource(this); + CleanupStack::PushL(pane); + pane->ConstructL(NULL); + pane->CreateL(reader); + + result = new (ELeave) CAiwMenuPane(*pane, aBaseMenuCmdId); + + CleanupStack::Pop(pane); + CleanupStack::PopAndDestroy(); // reader + + result->SetResourceSlotId( id ); + + return result; + } + + +void CAiwServiceHandlerImpl::DeleteAiwMenuPane(CAiwMenuPane* aAiwPane) + { + delete aAiwPane->iMenuPane; + aAiwPane->iMenuPane = NULL; + + // Reset iIdMap and extraText. + for(TInt i = 0; i < aAiwPane->iIdMap.Count(); i++) + { + aAiwPane->iIdMap[i].extraText.Close(); + } + aAiwPane->iIdMap.Reset(); + + // Remove the aiw menu pane from iMenuPanes array. + for(TInt i = 0; i < iMenuPanes.Count(); i++) + { + if(iMenuPanes[i] == aAiwPane) + { + iMenuPanes.Remove(i); + break; + } + } + + // Remove the aiw menu pane from iMenuLastInitialized array. + for(TInt i = 0; i < iLastInitialized.Count(); i++) + { + if(iLastInitialized[i] == aAiwPane) + { + iLastInitialized.Remove(i); + break; + } + } + + delete aAiwPane; + aAiwPane = NULL; + } + +const TInt resourceSlotIds[KMaxMenuResources] = + { + R_AIW_EMPTY_MENU_0, + R_AIW_EMPTY_MENU_1, + R_AIW_EMPTY_MENU_2, + R_AIW_EMPTY_MENU_3, + R_AIW_EMPTY_MENU_4, + R_AIW_EMPTY_MENU_5, + R_AIW_EMPTY_MENU_6, + R_AIW_EMPTY_MENU_7, + R_AIW_EMPTY_MENU_8, + R_AIW_EMPTY_MENU_9, + R_AIW_EMPTY_MENU_10, + R_AIW_EMPTY_MENU_11, + R_AIW_EMPTY_MENU_12, + R_AIW_EMPTY_MENU_13, + R_AIW_EMPTY_MENU_14, + R_AIW_EMPTY_MENU_15 + }; + + +TInt CAiwServiceHandlerImpl::ResourceIdForNextFreeSlot() + { + if (iNextFreeSlot < KMaxMenuResources) + { + return resourceSlotIds[iNextFreeSlot++]; + } + + return -1; + } + + +void CAiwServiceHandlerImpl::SetEmphasis(CCoeControl* /*aMenuControl*/,TBool /*aEmphasis*/) + { + } + + +void CAiwServiceHandlerImpl::ProcessCommandL(TInt /*aCommandId*/) + { + } + + +void Cleanup( TAny* aAny ) + { + RImplInfoPtrArray* implArray = + reinterpret_cast< RImplInfoPtrArray*> ( aAny ); + implArray->ResetAndDestroy(); + implArray->Close(); + } + + +void InterestCleanup( TAny* aAny ) + { + RPointerArray* interestArray = + reinterpret_cast*> ( aAny ); + + interestArray->ResetAndDestroy(); + } + +void FilteredCleanup( TAny* aAny ) + { + RPointerArray* filteredArray = + reinterpret_cast*> ( aAny ); + + filteredArray->Reset(); + } + + +void IntArrayCleanup(TAny* aAny) + { + RArray* intArray = + reinterpret_cast*> ( aAny ); + + intArray->Close(); + } + + +void CAiwServiceHandlerImpl::CopyMenuItemsL(CAiwMenuPane* aSource, CEikMenuPane& aDest, + TInt aStartIndex, TBool aIsSubmenu, TBool aSetAsItemSpecific) + { + TInt cmdId; + TInt inPos = aStartIndex; + + for (TInt i = 0; i < aSource->MenuPane().NumberOfItemsInPane(); i++) + { + cmdId = aSource->FindCmdId(i); + if (cmdId >= 0) + { + CEikMenuPaneItem::SData itemData = aSource->MenuPane().ItemData(cmdId); + + // The menu item might include alternative texts for a main menu level + // and for submenu. Use submenu string if it is intended so. + if(aIsSubmenu) + { + const TDesC& extraText = aSource->ExtraText(cmdId); + if(extraText.Length()) + { + itemData.iText.Zero(); + itemData.iText.Append(extraText); + } + } + + if ( aSetAsItemSpecific ) + { + itemData.iFlags |= EEikMenuItemSpecific; + } + + aDest.InsertMenuItemL(itemData, inPos++); + } + } + } + + + +TInt CAiwServiceHandlerImpl::SlotItemCmd(CEikMenuPane& aPane) + { + TInt index; + + for (TInt i = 0; i < KMaxMenuResources; i++) + { + if (aPane.MenuItemExists(EAiwMenuSlotBase + i, index)) + { + return EAiwMenuSlotBase + i; + } + } + + return -1; + } + + + +CAiwMenuPane* CAiwServiceHandlerImpl::MenuPaneForSlotCmd(TInt aCmdId) + { + TInt index = aCmdId - EAiwMenuSlotBase; + + if (index < KMaxMenuResources) + { + TInt resId = resourceSlotIds[index]; + for (TInt i = 0; i < iMenuPanes.Count(); i++) + { + if (iMenuPanes[i]->ResourceSlotId() == resId) + { + return iMenuPanes[i]; + } + } + } + + return NULL; + } + + + +CAiwServiceHandlerImpl::TAiwPlaceholderType CAiwServiceHandlerImpl::PlaceholderType( + CEikMenuPane& aPane, TInt aCmd, TBool& aTitleLocked) + { + CEikMenuPaneItem::SData& itemData = aPane.ItemData(aCmd); + + aTitleLocked = EFalse; + + if ((itemData.iCascadeId & AIW_CASCADE_ID) == AIW_CASCADE_ID) + { + if (itemData.iCascadeId & AIW_LOCK_SUBMENU_TITLE) + { + aTitleLocked = ETrue; + } + return EAiwPlaceholderCascade; + } + else if ((itemData.iCascadeId & AIW_INTELLIGENT_CASCADE_ID) == AIW_INTELLIGENT_CASCADE_ID) + { + if (itemData.iCascadeId & AIW_LOCK_SUBMENU_TITLE) + { + aTitleLocked = ETrue; + } + return EAiwPlaceholderIntelligentCascade; + } + + return EAiwPlaceholderNormal; + } + + +void CAiwServiceHandlerImpl::ConvertPlaceholderL(CEikMenuPane& aPane, TInt aCmd, + CAiwMenuPane& aAiwPane, const TDesC& aTitle, TBool aSetAsItemSpecific) + { + CEikMenuPaneItem::SData itemData = aPane.ItemData(aCmd); + TInt index; + + // Remenber index. + aPane.MenuItemExists(aCmd, index); + + // Remove placeholder item. + aPane.DeleteMenuItem(aCmd); + + // Replace aiw cascade id with actual menu resource id. + itemData.iCascadeId = aAiwPane.iResourceSlotId; + + if (aTitle.Length()) + { + itemData.iText.Copy(aTitle); + } + + // Set unused dynamic cmd id. + itemData.iCommandId = iSubmenuCmd++; + + if ( aSetAsItemSpecific ) + { + itemData.iFlags |= EEikMenuItemSpecific; + } + + // Insert cascade item. + aPane.InsertMenuItemL(itemData, index); + } + + +void CAiwServiceHandlerImpl::UnCascadeL(CEikMenuPane& aPane, TInt aCmd, + CAiwMenuPane& aAiwPane, TBool aSetAsItemSpecific) + { + CEikMenuPaneItem::SData itemData = aAiwPane.MenuPane().ItemData(aAiwPane.FindCmdId(0)); + TInt index; + + // Remenber index. + aPane.MenuItemExists(aCmd, index); + + // Remove placeholder item. + aPane.DeleteMenuItem(aCmd); + + // Uncascade + itemData.iCascadeId = 0; + + if ( aSetAsItemSpecific ) + { + itemData.iFlags |= EEikMenuItemSpecific; + } + + // Insert cascade item. + aPane.InsertMenuItemL(itemData, index); + } + + + +void CAiwServiceHandlerImpl::SkipMenuFields(TResourceReader& aReader) + { + aReader.ReadInt32(); // Skip cascade id + aReader.ReadInt32(); // Skip flags + aReader.ReadTPtrC(); // Skip text + aReader.ReadTPtrC(); // Skip extra text + aReader.ReadTPtrC(); // Skip bmpfile. + aReader.ReadInt16(); // Skip bmpid. + aReader.ReadInt16(); // Skip bmpmask. + aReader.ReadInt32(); // Skip extension. + } + + +TBool CAiwServiceHandlerImpl::IsAiwMenu(TInt aMenuResourceId) + { + TInt i; + + // First check if this is aiw submenu id + for (i = 0; i < KMaxMenuResources; i++) + { + if (aMenuResourceId == resourceSlotIds[i]) + { + return ETrue; + } + } + + // Then check if this menu is among attached menus. + for (i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->MenuId() == aMenuResourceId) + { + return ETrue; + } + } + + return EFalse; + } + + + +TBool CAiwServiceHandlerImpl::HandleSubmenuL(CEikMenuPane& aPane) + { + TInt slotcmd = SlotItemCmd(aPane); + if (slotcmd >= 0) + { + // aPane is aiw submenu. At this point it is empty and we must + // copy provider menu items to it. + CAiwMenuPane* aiwPane = MenuPaneForSlotCmd(slotcmd); + if (aiwPane) + { + CopyMenuItemsL(aiwPane, aPane, 0, ETrue, EFalse); + aPane.DeleteMenuItem(slotcmd); + iSubmenu = aiwPane; + return ETrue; + } + } + + return EFalse; + } + + + +TBool CAiwServiceHandlerImpl::GetSubmenuTitle(CEikMenuPane& aPane, TDes& aResult) + { + TInt index; + + aResult.Zero(); + while (aPane.MenuItemExists(AIW_SUBMENU_TITLE, index)) + { + CEikMenuPaneItem::SData& itemData = aPane.ItemData(AIW_SUBMENU_TITLE); + if (aResult.Length() == 0) + { + aResult.Copy(itemData.iText); + } + aPane.DeleteMenuItem(AIW_SUBMENU_TITLE); + return ETrue; + } + + return EFalse; + } + + + +CAiwCriteriaItem* CAiwServiceHandlerImpl::ConvertCriteriaItemPointerL(CAiwCriteriaItem* aCandidate) + { + for (TInt i = 0; i < iInterestList.Count(); i++) + { + if ((*iInterestList[i]) == (*aCandidate)) + { + // Already in list, aCandidate is not needed. + delete aCandidate; + return iInterestList[i]; + } + } + + CleanupStack::PushL(aCandidate); + User::LeaveIfError(iInterestList.Append(aCandidate)); + CleanupStack::Pop(); // aCandidate + + return aCandidate; + } + + + +void CAiwServiceHandlerImpl::FilterInterestListL(RPointerArray& aOriginal, + RPointerArray& aFiltered) + { + CAiwCriteriaItem* item; + + while (aOriginal.Count() > 0) + { + item = aOriginal[0]; + aOriginal.Remove(0); + item = ConvertCriteriaItemPointerL(item); + User::LeaveIfError(aFiltered.Append(item)); + } + aOriginal.Reset(); + } + + + +void CAiwServiceHandlerImpl::RemoveProvider(TInt aImplUid) + { + TInt i; + + // First go through bindings and remove all the + // references to given provider. + for (i = 0; i < iBaseBindings.Count(); i++) + { + iBaseBindings[i]->RemoveProvider(aImplUid); + } + + for (i = 0; i < iMenuBindings.Count(); i++) + { + iMenuBindings[i]->RemoveProvider(aImplUid); + } + + // Then remove provider from the owner list and delete it. + for (i = 0; i < iProviders.Count(); i++) + { + if (iProviders[i]->ImplementationUid().iUid == aImplUid) + { + delete iProviders[i]; + iProviders.Remove(i); + i--; + } + } + } + + +void CAiwServiceHandlerImpl::AddProviderL(TUid aImplUid, CAiwCriteriaItem* aItem) + { + TInt i; + CAiwServiceIfBase* iface = iEcomMonitor->CreateImplementationL(aImplUid); + + if (iface) + { + CleanupStack::PushL(iface); + iface->AddCriteria(aItem); + User::LeaveIfError(iProviders.Append( iface )); + CleanupStack::Pop(iface); + + for (i = 0; i < iBaseBindings.Count(); i++) + { + if (iBaseBindings[i]->HasCriteriaItem(*aItem) != KErrNotFound) + { + iBaseBindings[i]->AddProviderL(iface, aImplUid == aItem->DefaultProvider()); + iface->InitialiseL(*this, iBaseBindings[i]->Interest()); + } + } + + for (i = 0; i < iMenuBindings.Count(); i++) + { + if (iMenuBindings[i]->HasCriteriaItem(*aItem) != KErrNotFound) + { + iMenuBindings[i]->AddProviderL(iface, aImplUid == aItem->DefaultProvider()); + iface->InitialiseL(*this, iMenuBindings[i]->Interest()); + } + } + } + } + + + +TInt CAiwServiceHandlerImpl::SynchronizeCallBack(TAny* aImpl) + { + CAiwServiceHandlerImpl* impl = reinterpret_cast(aImpl); + TRAPD(err, impl->SynchronizeDbL()); + return err; + } + + + +void CAiwServiceHandlerImpl::SynchronizeDbL() + { + TInt i; + RArray providers; + RImplInfoPtrArray infoArray; + + CleanupStack::PushL( TCleanupItem( IntArrayCleanup, &providers ) ); + CleanupStack::PushL( TCleanupItem( Cleanup, &infoArray ) ); + + for (i = 0; i < iInterestList.Count(); i++) + { + if (iInterestList[i]->RomOnly()) // Rom-only criterias can be skipped. + { + continue; + } + + providers.Reset(); + infoArray.ResetAndDestroy(); + ListProvidersForCriteriaL(providers, *(iInterestList[i])); + iEcomMonitor->ListImplemetationsL(infoArray, iInterestList[i]); + HandleRemovedProviders(providers, infoArray); + HandleNewProvidersL(providers, infoArray, iInterestList[i]); + } + + CleanupStack::PopAndDestroy(2); // providers, infoArray + } + + +void CAiwServiceHandlerImpl::HandleRemovedProviders(RArray& aInMemory, + RImplInfoPtrArray& aInSystem) + { + TInt i, j; + + for (i = 0; i < aInMemory.Count(); i++) + { + for (j = 0; j < aInSystem.Count(); j++) + { + if (aInSystem[j]->ImplementationUid().iUid == aInMemory[i]) + { + break; + } + } + if (j >= aInSystem.Count()) // Was removed from system. + { + RemoveProvider(aInMemory[i]); + } + } + } + + +void CAiwServiceHandlerImpl::HandleNewProvidersL(RArray& aInMemory, + RImplInfoPtrArray& aInSystem, CAiwCriteriaItem* aItem) + { + TInt i; + + for (i = 0; i < aInSystem.Count(); i++) + { + if (aInMemory.Find(aInSystem[i]->ImplementationUid().iUid) == KErrNotFound) + { + AddProviderL(aInSystem[i]->ImplementationUid(), aItem); + } + } + } + +void CAiwServiceHandlerImpl::MenuLaunched() + { + ClearMenuPaneArray(); + iNextFreeSlot = 0; + iLastInitialized.Reset(); + + // Reset the iMenuPane pointers from iMenuBindings. + for(TInt i = 0; i < iMenuBindings.Count(); i++) + { + iMenuBindings[i]->SetMenuPane(NULL); + } + } + +// End of file