locationmapnavfw/aiwprovider/src/mnaiwprovider.cpp
branchRCL_3
changeset 44 2b4ea9893b66
parent 42 02ba3f1733c6
child 45 6b6920c56e2f
equal deleted inserted replaced
42:02ba3f1733c6 44:2b4ea9893b66
     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:  CMnAiwProvider class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <badesca.h>
       
    20 
       
    21 #include <aknlistquerydialog.h>
       
    22 #include <AknGlobalNote.h>
       
    23 
       
    24 #include <AiwMenu.h>
       
    25 #include <AiwGenericParam.hrh>
       
    26 #include <AiwCommon.hrh>
       
    27 #include <aknenv.h>
       
    28 
       
    29 #include <ecom/implementationproxy.h>
       
    30 
       
    31 #include <mnaiwproviderres.rsg>
       
    32 #include "mnaiwprovideruids.hrh"
       
    33 
       
    34 #include <lbsposition.h>
       
    35 
       
    36 #include <mnprovider.h>
       
    37 #include <mnproviderfinder.h>
       
    38 #include <mnmapview.h>
       
    39 #include <mnnavigator.h>
       
    40 #include <mngeocoder.h>
       
    41 #include <mnutils.h>
       
    42 #include <mnappservices.hrh>
       
    43 
       
    44 #include "mnaiwdebug.h"
       
    45 #include "mnaiwinternal.h"
       
    46 
       
    47 #include "mnaiwservices.h"
       
    48 #include "mnaiwmenus.hrh"
       
    49 
       
    50 #include "mnaiwprovider.h"
       
    51 
       
    52 // =========================== LOCAL FUNCTIONS =================================
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 //  Cleanup item for RPointerArray<CMnProvider>
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 void CleanupProvidersArray( TAny* aArray )
       
    59     {
       
    60     ( static_cast<RPointerArray<CMnProvider>*>( aArray ) )->ResetAndDestroy();
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 //  Identity relation for providers. Based on UID
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 TBool ProvidersMatchByUid( const CMnProvider& aOne, const CMnProvider& aAnother )
       
    68 	{
       
    69 	return ( aOne.Uid().iUid == aAnother.Uid().iUid );
       
    70 	}
       
    71 
       
    72 // ========================== MEMBER FUNCTIONS =================================
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 CMnAiwProvider* CMnAiwProvider::NewL()
       
    78     {
       
    79     LOG( "CMnAiwProvider::NewL in" );
       
    80 
       
    81     CMnAiwProvider* self = new (ELeave) CMnAiwProvider();
       
    82     CleanupStack::PushL(self);
       
    83     self->ConstructL();
       
    84     CleanupStack::Pop(self);
       
    85 
       
    86     LOG( "CMnAiwProvider::NewL out" );
       
    87     return self;
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 CMnAiwProvider::CMnAiwProvider()
       
    94     {
       
    95     }
       
    96 
       
    97 // -----------------------------------------------------------------------------
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 CMnAiwProvider::~CMnAiwProvider()
       
   101     {
       
   102     LOG( "~CMnAiwProvider in" );
       
   103 
       
   104     delete iEventList;
       
   105 
       
   106     CloseAllHandlers();
       
   107     iHandlers.Close();
       
   108 
       
   109     if ( iEikon )
       
   110         {
       
   111         iEikon->DeleteResourceFile( iResourceOffset );
       
   112         }
       
   113     iMnProviders.ResetAndDestroy();
       
   114 
       
   115     LOG( "~CMnAiwProvider out" );
       
   116     }
       
   117 
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 void CMnAiwProvider::ConstructL()
       
   123     {
       
   124     LOG( "CMnAiwProvider::ConstructL in" );
       
   125 #ifdef _DEBUG
       
   126     TTime start;
       
   127     start.UniversalTime();
       
   128 #endif
       
   129 
       
   130     iEikon = CEikonEnv::Static();
       
   131 
       
   132     TRAPD( err, MnUtils::FindLocalizedResourceFileL( iEikon->FsSession(), KAiwResourceFile, iResourceFilename ) );
       
   133     if ( err == KErrNotFound )
       
   134         {
       
   135         // try to find it with the name it had in 3.1
       
   136         // this is needed for the case, when upgrade is installed on 3.1-based terminals
       
   137         MnUtils::FindLocalizedResourceFileL( iEikon->FsSession(), KAiwResourceFileOld, iResourceFilename );
       
   138         }
       
   139     iResourceOffset = iEikon->AddResourceFileL( iResourceFilename );
       
   140 
       
   141     iEventList = CAiwGenericParamList::NewL();
       
   142 
       
   143 #ifdef _DEBUG
       
   144     TTime finish;
       
   145     finish.UniversalTime();
       
   146     TTimeIntervalMicroSeconds elapsed = finish.MicroSecondsFrom( start );
       
   147     LOG1( "CMnAiwProvider::ConstructL out ( in %ld microseconds ) ", elapsed.Int64() );
       
   148 #endif
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // -----------------------------------------------------------------------------
       
   153 //
       
   154 TInt CMnAiwProvider::GetAiwServiceCommandIdL( const CAiwGenericParamList& aInParamList )
       
   155     {
       
   156     TInt index = 0;
       
   157     const TAiwGenericParam* param = aInParamList.FindFirst( index, EGenericParamServiceCommand );
       
   158     if ( index < 0 )
       
   159         {
       
   160         LOG( "CMnAiwProvider::GetServiceCommandL: param not found" );
       
   161         User::Leave( KErrArgument );
       
   162         }
       
   163 
       
   164     TInt32 num = 0;
       
   165     const TAiwVariant& val = param->Value();
       
   166     if ( !val.Get( num ) )
       
   167         {
       
   168         LOG( "CMnAiwProvider::GetServiceCommandL: param value not found" );
       
   169         User::Leave( KErrArgument );
       
   170         }
       
   171     return num;
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // From CAiwServiceIfBase
       
   176 // -----------------------------------------------------------------------------
       
   177 //
       
   178 void CMnAiwProvider::InitialiseL(
       
   179     MAiwNotifyCallback& /*aFrameworkCallback*/,
       
   180     const RCriteriaArray& /*aInterest*/ )
       
   181     {
       
   182     LOG("CMnAiwProvider::InitialiseL");
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // From CAiwServiceIfBase
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 void CMnAiwProvider::HandleServiceCmdL(
       
   190     const TInt& aCmdId,
       
   191     const CAiwGenericParamList& aInParamList,
       
   192     CAiwGenericParamList& aOutParamList,
       
   193     TUint aCmdOptions,
       
   194     const MAiwNotifyCallback* aCallback)
       
   195     {
       
   196     LOG1("CMnAiwProvider::HandleServiceCmdL cmdId: %x", aCmdId);
       
   197 
       
   198     if ( aCmdOptions & KAiwOptCancel )
       
   199         {
       
   200         // this is call to cancel async request,
       
   201         // not supported yet - ignoring, but not starting new one.
       
   202         LOG("CMnAiwProvider::HandleServiceCmdL attempt to cancel, exit");
       
   203         return;
       
   204         }
       
   205 
       
   206     CMnAiwCommandHandlerBase::TAiwParameters
       
   207         aiwParams( aInParamList, aOutParamList, aCallback );
       
   208 
       
   209     switch ( aCmdId )
       
   210         {
       
   211         case KAiwCmdMnShowMap:
       
   212         case KAiwCmdMnNavigateTo:
       
   213             {
       
   214             TInt err = KErrNone;
       
   215             TBool stop = EFalse;
       
   216             while ( !stop )
       
   217                 {
       
   218                 TRAP( err, ProcessSyncAiwCommandL( aCmdId, aiwParams ) );
       
   219                 ProcessAiwCommandResultL( aCmdId, aiwParams, err, stop );
       
   220                 }
       
   221             User::LeaveIfError( err );
       
   222             }
       
   223             break;
       
   224 
       
   225         case KAiwCmdMnSelectFromMap:
       
   226         case KAiwCmdMnCoordByAddr:
       
   227         case KAiwCmdMnAddrByCoord:
       
   228             if ( !aCallback )
       
   229                 {
       
   230                 User::Leave( KErrArgument );
       
   231                 }
       
   232             StartAsyncAiwCommandL( aCmdId, aiwParams );
       
   233             break;
       
   234 
       
   235         default:
       
   236             User::Leave( KErrNotSupported );
       
   237             break;
       
   238         }
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // -----------------------------------------------------------------------------
       
   243 //
       
   244 void CMnAiwProvider::ProcessSyncAiwCommandL(
       
   245     TInt aCommandId,
       
   246     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams )
       
   247     {
       
   248     LOG("CMnAiwProvider::ProcessSyncAiwCommandL in");
       
   249 
       
   250 	CMnAiwCommandHandlerBase* handler = HandlerL( aCommandId, aAiwParams );
       
   251     handler->StartL();
       
   252 
       
   253     LOG("CMnAiwProvider::ProcessSyncAiwCommandL out");
       
   254     }
       
   255 
       
   256 // -----------------------------------------------------------------------------
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CMnAiwProvider::StartAsyncAiwCommandL(
       
   260     TInt aCommandId,
       
   261     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams )
       
   262     {
       
   263     LOG("CMnAiwProvider::StartAsyncAiwCommandL in");
       
   264 
       
   265     TBool stop = EFalse;
       
   266     while ( !stop )
       
   267         {
       
   268         TInt err = KErrNone;
       
   269         CMnAiwCommandHandlerBase* handler = NULL;
       
   270         TRAP( err, handler = HandlerL( aCommandId, aAiwParams ) );
       
   271 
       
   272         if ( !err )
       
   273             {
       
   274             handler->Start( *this );
       
   275             break;
       
   276             }
       
   277         else
       
   278             {
       
   279             if ( handler )
       
   280                 {
       
   281                 CloseHandler( handler );
       
   282                 }
       
   283 
       
   284             if ( err == KErrCancel )
       
   285                 {
       
   286                 // must stop if provider selection fails
       
   287                 stop = ETrue;
       
   288                 }
       
   289             else
       
   290                 {
       
   291                 // this is error from command start
       
   292                 ProcessAiwCommandResultL( aCommandId, aAiwParams, err, stop );
       
   293                 }
       
   294 
       
   295             if ( stop )
       
   296                 {
       
   297                 // couldn't start command
       
   298                 NotifyAiwObserver( aCommandId, aAiwParams, err );
       
   299                 }
       
   300             }
       
   301         }
       
   302 
       
   303     LOG("CMnAiwProvider::StartAsyncAiwCommandL out");
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 CMnAiwCommandHandlerBase* CMnAiwProvider::HandlerL(
       
   310     TInt aCommandId,
       
   311     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams )
       
   312     {
       
   313     LOG("CMnAiwProvider::HandlerL in");
       
   314 
       
   315     CMnProvider& provider = SelectProviderL( aCommandId, aAiwParams );
       
   316 
       
   317     CMnAiwCommandHandlerBase::TRunMode runMode =
       
   318         CMnAiwCommandHandlerBase::RequestedRunModeL( aAiwParams );
       
   319 
       
   320     if ( runMode == CMnAiwCommandHandlerBase::ERunModeDefault )
       
   321         {
       
   322         runMode = CMnAiwCommandHandlerBase::DefaultRunMode( aCommandId );
       
   323         }
       
   324 
       
   325     if ( runMode == CMnAiwCommandHandlerBase::ERunModeDefault )
       
   326         {
       
   327         User::Leave( KErrNotSupported );
       
   328         }
       
   329 
       
   330     CMnAiwCommandHandlerBase* handler = FindWorkingHandler( aCommandId, provider, runMode );
       
   331 
       
   332     if ( !handler )
       
   333         {
       
   334         handler = CMnAiwCommandHandlerBase::CreateHandlerL( aCommandId, provider, runMode );
       
   335         CleanupStack::PushL( handler );
       
   336         handler->SetExitObserverL( *this );
       
   337         iHandlers.AppendL( handler );
       
   338         CleanupStack::Pop( handler );
       
   339         }
       
   340     else
       
   341         {
       
   342         LOG("CMnAiwProvider::HandlerL, working handler found, reusing");
       
   343         handler->ResetParametersL();
       
   344         }
       
   345 
       
   346     handler->SetParametersL( aAiwParams );
       
   347 
       
   348     LOG("CMnAiwProvider::HandlerL out");
       
   349     return handler;
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // -----------------------------------------------------------------------------
       
   354 //
       
   355 void CMnAiwProvider::HandleAsyncAiwCmdCompletedL(
       
   356     CMnAiwCommandHandlerBase* aHandler,
       
   357     TInt aResult )
       
   358     {
       
   359     LOG1("CMnAiwProvider::HandleAsyncAiwCmdCompletedL in, result %d", aResult );
       
   360 
       
   361     TInt command = aHandler->CommandId();
       
   362     CMnAiwCommandHandlerBase::TAiwParameters aiwParams = aHandler->AiwParameters();
       
   363 
       
   364     CloseHandler( aHandler );
       
   365 
       
   366     TBool stop = EFalse;
       
   367     ProcessAiwCommandResultL( command, aiwParams, aResult, stop );
       
   368 
       
   369     if ( stop )
       
   370         {
       
   371         NotifyAiwObserver( command, aiwParams, aResult );
       
   372         }
       
   373     else
       
   374         {
       
   375         StartAsyncAiwCommandL( command, aiwParams );
       
   376         }
       
   377 
       
   378     LOG("CMnAiwProvider::HandleAsyncAiwCmdCompletedL out");
       
   379     }
       
   380 
       
   381 // -----------------------------------------------------------------------------
       
   382 // -----------------------------------------------------------------------------
       
   383 //
       
   384 void CMnAiwProvider::HandleProviderExit(
       
   385     CMnAiwCommandHandlerBase* aHandler )
       
   386     {
       
   387     LOG("CMnAiwProvider::HandleProviderExit in" );
       
   388 
       
   389 	CloseHandler( aHandler );
       
   390 
       
   391     LOG("CMnAiwProvider::HandleProviderExit out");
       
   392     }
       
   393 
       
   394 // -----------------------------------------------------------------------------
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 void CMnAiwProvider::NotifyAiwObserver(
       
   398     TInt aCommandId,
       
   399     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams,
       
   400     TInt aResult )
       
   401     {
       
   402     LOG2("CMnAiwProvider::NotifyAiwObserver in, command 0x%X, result %d", aCommandId, aResult);
       
   403     __ASSERT_DEBUG( aAiwParams.Callback(), Panic( KErrGeneral) );
       
   404 
       
   405     MAiwNotifyCallback* callback = const_cast<MAiwNotifyCallback*>( aAiwParams.Callback() );
       
   406 
       
   407     TInt err = KErrNone;
       
   408     iEventList->Reset();
       
   409     if ( aResult )
       
   410         {
       
   411         TAiwGenericParam error( EGenericParamError, TAiwVariant( aResult ) );
       
   412         TRAP_IGNORE( iEventList->AppendL( error ) );
       
   413 
       
   414         TRAP( err, callback->HandleNotifyL(
       
   415             aCommandId, KAiwEventError, *iEventList, aAiwParams.InList() ) );
       
   416         }
       
   417     else
       
   418         {
       
   419         TRAP( err, callback->HandleNotifyL(
       
   420             aCommandId, KAiwEventCompleted, *iEventList, aAiwParams.InList() ) );
       
   421         }
       
   422 
       
   423     LOG("CMnAiwProvider::NotifyAiwObserver out");
       
   424     }
       
   425 
       
   426 // -----------------------------------------------------------------------------
       
   427 // -----------------------------------------------------------------------------
       
   428 //
       
   429 void CMnAiwProvider::CloseHandler( CMnAiwCommandHandlerBase* aHandler )
       
   430     {
       
   431     LOG("CMnAiwProvider::CloseHandler in");
       
   432 
       
   433     if ( aHandler->IsActive() )
       
   434     	{
       
   435     	// make sure we are not panicked if async handler is closed while active.
       
   436     	// at first, command is only cancelled. Cancel will call this method again,
       
   437     	// then this object will be deleted.
       
   438     	aHandler->Cancel();
       
   439     	}
       
   440 
       
   441 	TInt index = iHandlers.Find( aHandler );
       
   442 	if ( index != KErrNotFound )
       
   443 	    {
       
   444     	delete aHandler;
       
   445     	iHandlers.Remove( index );
       
   446 	    }
       
   447     LOG1("CMnAiwProvider::CloseHandler out, deleted handler %d", index);
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // -----------------------------------------------------------------------------
       
   452 //
       
   453 void CMnAiwProvider::ProcessAiwCommandResultL( 
       
   454     TInt aAiwCommandId, 
       
   455     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams,
       
   456     TInt aResult, 
       
   457     TBool& aStop )
       
   458     {
       
   459     LOG1("CMnAiwProvider::ProcessAiwCommandResultL in, result %d", aResult);
       
   460 
       
   461     TBool banMessages = EFalse;
       
   462     if ( CMnAiwCommandHandlerBase::IsErrorMessageDisabledL( aAiwParams ) )
       
   463         {
       
   464         banMessages = ETrue;
       
   465         }
       
   466     
       
   467     TInt unusedProviderId( 0 );
       
   468     TInt messageId( 0 );
       
   469     
       
   470     if ( aResult == KErrNone || aResult == KErrCancel )
       
   471         {
       
   472         aStop = ETrue;
       
   473         }
       
   474     else if ( CMnAiwCommandHandlerBase::IsProviderSpecifiedL( aAiwParams, unusedProviderId ) ) 
       
   475         {
       
   476         aStop = ETrue;
       
   477         messageId = R_MN_ERROR_SERVICE_UNAVAILABLE;
       
   478         }
       
   479     else if ( NumSuitableProviders( aAiwCommandId ) < 2 )
       
   480         {
       
   481         aStop = ETrue;
       
   482         messageId = R_MN_ERROR_NO_PROVIDER;
       
   483         }
       
   484     else
       
   485         {
       
   486         aStop = EFalse;
       
   487         messageId = R_MN_ERROR_SERVICE_UNAVAILABLE;
       
   488         }
       
   489     
       
   490     if ( !banMessages && messageId )
       
   491         {
       
   492         ErrorNote( messageId );
       
   493         }
       
   494 
       
   495     LOG("CMnAiwProvider::ProcessAiwCommandResultL out");
       
   496     }
       
   497 
       
   498 // -----------------------------------------------------------------------------
       
   499 // From CAiwServiceIfMenu
       
   500 // -----------------------------------------------------------------------------
       
   501 //
       
   502 void CMnAiwProvider::InitializeMenuPaneL(
       
   503     CAiwMenuPane& aMenuPane,
       
   504     TInt aIndex,
       
   505     TInt /*aCascadeId*/,
       
   506     const CAiwGenericParamList& aInParamList)
       
   507     {
       
   508     LOG( "CMnAiwProvider::InitializeMenuPaneL in" );
       
   509 
       
   510     TInt svcCmdId = GetAiwServiceCommandIdL( aInParamList );
       
   511     if ( !IsServiceAvailableL( svcCmdId ) )
       
   512         {
       
   513         LOG1( "CMnAiwProvider::InitializeMenuPaneL svc 0x%X is not available, out", svcCmdId );
       
   514         return;
       
   515         }
       
   516 
       
   517     switch ( svcCmdId )
       
   518         {
       
   519         case KAiwCmdMnShowMap:
       
   520             aMenuPane.AddMenuItemsL(
       
   521                 iResourceFilename,
       
   522                 R_MN_AIWMENU_SHOW_ON_MAP,
       
   523                 KAiwCmdMnShowMap,
       
   524                 aIndex);
       
   525             break;
       
   526 
       
   527         case KAiwCmdMnSelectFromMap:
       
   528             aMenuPane.AddMenuItemsL(
       
   529                 iResourceFilename,
       
   530                 R_MN_AIWMENU_SELECT_FROM_MAP,
       
   531                 KAiwCmdMnSelectFromMap,
       
   532                 aIndex);
       
   533             break;
       
   534 
       
   535         case KAiwCmdMnNavigateTo:
       
   536             aMenuPane.AddMenuItemsL(
       
   537                 iResourceFilename,
       
   538                 R_MN_AIWMENU_NAVIGATE_TO,
       
   539                 KAiwCmdMnNavigateTo,
       
   540                 aIndex);
       
   541             break;
       
   542 
       
   543         case KAiwCmdMnCoordByAddr:
       
   544             aMenuPane.AddMenuItemsL(
       
   545                 iResourceFilename,
       
   546                 R_MN_AIWMENU_FETCH_COORDINATES,
       
   547                 KAiwCmdMnCoordByAddr,
       
   548                 aIndex);
       
   549             break;
       
   550 
       
   551         case KAiwCmdMnAddrByCoord:
       
   552             aMenuPane.AddMenuItemsL(
       
   553                 iResourceFilename,
       
   554                 R_MN_AIWMENU_FETCH_ADDRESS,
       
   555                 KAiwCmdMnAddrByCoord,
       
   556                 aIndex);
       
   557             break;
       
   558         }
       
   559     LOG( "CMnAiwProvider::InitializeMenuPaneL out" );
       
   560     }
       
   561 
       
   562 
       
   563 // -----------------------------------------------------------------------------
       
   564 // From CAiwServiceIfMenu
       
   565 // -----------------------------------------------------------------------------
       
   566 //
       
   567 void CMnAiwProvider::HandleMenuCmdL(
       
   568     TInt aMenuCmdId,
       
   569     const CAiwGenericParamList& aInParamList,
       
   570     CAiwGenericParamList& aOutParamList,
       
   571     TUint aCmdOptions,
       
   572     const MAiwNotifyCallback* aCallback)
       
   573     {
       
   574     LOG( "CMnAiwProvider::HandleMenuCmdL in" );
       
   575 
       
   576     TInt svcCmdId = KAiwCmdNone;
       
   577 
       
   578     switch ( aMenuCmdId )
       
   579         {
       
   580         case EMnAiwMenuCmdShowOnMap:
       
   581             svcCmdId = KAiwCmdMnShowMap;
       
   582             break;
       
   583 
       
   584         case EMnAiwMenuCmdSelectFromMap:
       
   585             svcCmdId = KAiwCmdMnSelectFromMap;
       
   586             break;
       
   587 
       
   588         case EMnAiwMenuCmdNavigateTo:
       
   589             svcCmdId = KAiwCmdMnNavigateTo;
       
   590             break;
       
   591 
       
   592         case EMnAiwMenuCmdFetchAddress:
       
   593             svcCmdId = KAiwCmdMnAddrByCoord;
       
   594             break;
       
   595 
       
   596         case EMnAiwMenuCmdFetchCoordinates:
       
   597             svcCmdId = KAiwCmdMnCoordByAddr;
       
   598             break;
       
   599         }
       
   600 
       
   601     HandleServiceCmdL( svcCmdId, aInParamList, aOutParamList, aCmdOptions, aCallback );
       
   602 
       
   603     LOG( "CMnAiwProvider::HandleMenuCmdL out" );
       
   604     }
       
   605 
       
   606 // -----------------------------------------------------------------------------
       
   607 // -----------------------------------------------------------------------------
       
   608 //
       
   609 TBool CMnAiwProvider::IsServiceAvailableL( TInt aAiwCommandId )
       
   610     {
       
   611     UpdateProvidersListL();
       
   612     return NumSuitableProviders( aAiwCommandId ) > 0;
       
   613     }
       
   614 
       
   615 // -----------------------------------------------------------------------------
       
   616 // -----------------------------------------------------------------------------
       
   617 //
       
   618 void CMnAiwProvider::UpdateProvidersListL()
       
   619     {
       
   620     // get new list of providers
       
   621     RPointerArray<CMnProvider> providers;
       
   622     CleanupStack::PushL( TCleanupItem( CleanupProvidersArray, &providers ) );
       
   623     MnProviderFinder::FindProvidersL( providers );
       
   624     
       
   625     // merge new list with current list of providers
       
   626     TIdentityRelation<CMnProvider> byUid( ProvidersMatchByUid );
       
   627 
       
   628     // detect removed providers
       
   629     for ( TInt i = iMnProviders.Count() - 1; i >= 0 ; i-- )
       
   630         {
       
   631         if ( providers.Find( iMnProviders[i], byUid ) == KErrNotFound )
       
   632             {
       
   633             LOG1("CMnAiwProvider::UpdateProvidersListL, provider 0x%X removed", 
       
   634                 iMnProviders[i]->Uid().iUid );
       
   635             CloseHandlers( iMnProviders[i] );
       
   636             delete iMnProviders[i];
       
   637             iMnProviders.Remove( i );
       
   638             }
       
   639         }
       
   640 
       
   641     // detect new providers
       
   642     for ( TInt i = providers.Count() - 1; i >=0 ; i-- )
       
   643 		{
       
   644 		if ( iMnProviders.Find( providers[i], byUid ) == KErrNotFound )
       
   645 			{
       
   646             LOG1("CMnAiwProvider::UpdateProvidersListL, new provider 0x%X added", 
       
   647                 providers[i]->Uid().iUid );
       
   648 			iMnProviders.AppendL( providers[i] );
       
   649 			providers.Remove( i ); // ownership is moved to iMnProviders
       
   650 			}
       
   651 		}
       
   652 
       
   653 	CleanupStack::PopAndDestroy( &providers );
       
   654     }
       
   655 
       
   656 // -----------------------------------------------------------------------------
       
   657 // -----------------------------------------------------------------------------
       
   658 //
       
   659 CMnAiwCommandHandlerBase* CMnAiwProvider::FindWorkingHandler(
       
   660     TInt aAiwCommandId,
       
   661     const CMnProvider& aProvider,
       
   662     CMnAiwCommandHandlerBase::TRunMode aRunMode )
       
   663     {
       
   664     for ( TInt i = 0; i < iHandlers.Count(); i++ )
       
   665         {
       
   666         CMnAiwCommandHandlerBase* handler = iHandlers[i];
       
   667         if ( handler->Provider().Uid() == aProvider.Uid() &&
       
   668              handler->CommandId() == aAiwCommandId &&
       
   669              handler->RunMode() == aRunMode &&
       
   670              !handler->IsActive() ) // active async handler cannot be reused
       
   671             {
       
   672             return iHandlers[i];
       
   673             }
       
   674         }
       
   675     return NULL;
       
   676     }
       
   677 
       
   678 // -----------------------------------------------------------------------------
       
   679 // -----------------------------------------------------------------------------
       
   680 //
       
   681 void CMnAiwProvider::CloseHandlers( const CMnProvider* aProvider )
       
   682 	{
       
   683 	for ( TInt i = iHandlers.Count() - 1; i >= 0 ; i-- )
       
   684 		{
       
   685 		if ( ProvidersMatchByUid( iHandlers[i]->Provider(), *aProvider ) )
       
   686 			{
       
   687 			CloseHandler( iHandlers[i] ); // this will modify the handlers list
       
   688 			}
       
   689 		}
       
   690 	}
       
   691 
       
   692 // -----------------------------------------------------------------------------
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 void CMnAiwProvider::CloseAllHandlers()
       
   696 	{
       
   697 	for ( TInt i = iHandlers.Count() - 1; i >= 0 ; i-- )
       
   698 		{
       
   699 		CloseHandler( iHandlers[i] ); // this will modify the handlers list
       
   700 		}
       
   701 	}
       
   702 
       
   703 // -----------------------------------------------------------------------------
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 void CMnAiwProvider::GetSuitableProvidersL(
       
   707     TInt aAiwCommandId,
       
   708     RPointerArray<CMnProvider>& aProviders )
       
   709     {
       
   710     LOG1("CMnAiwProvider::GetSuitableProvidersL in, Cmd %x", aAiwCommandId);
       
   711 
       
   712     CMnProvider::TService serviceNeeded = CMnProvider::EServiceNone;
       
   713     TInt featuresNeeded = 0;
       
   714 
       
   715     CMnAiwCommandHandlerBase::AppServiceAndFeatureNeeded(
       
   716         aAiwCommandId, serviceNeeded, featuresNeeded );
       
   717 
       
   718     for ( TInt i = 0; i < iMnProviders.Count(); i++ )
       
   719         {
       
   720         CMnProvider* provider = iMnProviders[i];
       
   721 
       
   722         if ( ( provider->SupportedServices() & serviceNeeded ) &&
       
   723              ( provider->SupportedFeatures( serviceNeeded ) & featuresNeeded ) )
       
   724             {
       
   725             LOG1("CMnAiwProvider::GetSuitableProvidersL using 0x%X", provider->Uid().iUid);
       
   726             aProviders.AppendL( provider );
       
   727             }
       
   728         }
       
   729     LOG("CMnAiwProvider::GetSuitableProvidersL out");
       
   730     }
       
   731 
       
   732 // -----------------------------------------------------------------------------
       
   733 // -----------------------------------------------------------------------------
       
   734 //
       
   735 TInt CMnAiwProvider::NumSuitableProviders( TInt aAiwCommandId )
       
   736     {
       
   737     CMnProvider::TService serviceNeeded = CMnProvider::EServiceNone;
       
   738     TInt featuresNeeded = 0;
       
   739 
       
   740     CMnAiwCommandHandlerBase::AppServiceAndFeatureNeeded(
       
   741         aAiwCommandId, serviceNeeded, featuresNeeded );
       
   742 
       
   743     TInt count = 0;
       
   744     for ( TInt i = 0; i < iMnProviders.Count(); i++ )
       
   745         {
       
   746         CMnProvider* provider = iMnProviders[i];
       
   747 
       
   748         if ( ( provider->SupportedServices() & serviceNeeded ) &&
       
   749              ( provider->SupportedFeatures( serviceNeeded ) & featuresNeeded ) )
       
   750             {
       
   751             count++;
       
   752             }
       
   753         }
       
   754     return count;
       
   755     }
       
   756 
       
   757 // -----------------------------------------------------------------------------
       
   758 // -----------------------------------------------------------------------------
       
   759 //
       
   760 CMnProvider& CMnAiwProvider::SelectProviderL( 
       
   761     TInt aAiwCommandId,
       
   762     CMnAiwCommandHandlerBase::TAiwParameters& aAiwParams )
       
   763     {
       
   764     CMnProvider* provider = NULL;
       
   765 
       
   766     RPointerArray<CMnProvider> mnProviders; // array does _not_ own items
       
   767     CleanupClosePushL( mnProviders );
       
   768 
       
   769     UpdateProvidersListL();
       
   770     GetSuitableProvidersL( aAiwCommandId, mnProviders );
       
   771     
       
   772     TInt requestedProviderId( 0 );
       
   773     if ( CMnAiwCommandHandlerBase::IsProviderSpecifiedL( aAiwParams, requestedProviderId ) )
       
   774         {
       
   775         for ( int i = 0; i < mnProviders.Count(); i++ )
       
   776             {
       
   777             if ( mnProviders[i]->Uid().iUid == requestedProviderId )
       
   778                 {
       
   779                 provider = mnProviders[i];
       
   780                 break;
       
   781                 }
       
   782             }
       
   783         
       
   784         if ( !provider )
       
   785             {
       
   786             User::Leave( KErrArgument );
       
   787             }
       
   788         }
       
   789     else if ( mnProviders.Count() > 1 )
       
   790         {
       
   791         TInt index = KErrNotFound;
       
   792         ExecuteSelectionDialogL( index, mnProviders );
       
   793             provider = mnProviders[index];
       
   794         }
       
   795     else if ( mnProviders.Count() == 1 )
       
   796         {
       
   797         provider = mnProviders[0];
       
   798         }
       
   799     else
       
   800         {
       
   801         User::Leave( KErrNotSupported );
       
   802         }
       
   803 
       
   804     CleanupStack::PopAndDestroy( &mnProviders );
       
   805     LOG1("CMnAiwProvider::SelectProviderL, selected 0x%X", provider->Uid().iUid);
       
   806     return *provider;
       
   807     }
       
   808 
       
   809 // -----------------------------------------------------------------------------
       
   810 // -----------------------------------------------------------------------------
       
   811 //
       
   812 void CMnAiwProvider::ExecuteSelectionDialogL(
       
   813     TInt& aIndex,
       
   814     RPointerArray<CMnProvider>& aProviders )
       
   815     {
       
   816     CDesCArraySeg* textArray = new (ELeave) CDesCArraySeg( aProviders.Count() );
       
   817     CleanupStack::PushL( textArray );
       
   818 
       
   819     for ( TInt i = 0; i < aProviders.Count(); i++ )
       
   820         {
       
   821         TPtrC shortName;
       
   822         aProviders[i]->GetShortName( shortName );
       
   823         textArray->AppendL( shortName );
       
   824         }
       
   825 
       
   826     CAknListQueryDialog* dlg = new (ELeave) CAknListQueryDialog( &aIndex );
       
   827     dlg->PrepareLC( R_MN_PROVIDER_LIST_QUERY );
       
   828 
       
   829     dlg->SetItemTextArray( textArray );
       
   830     dlg->SetOwnershipType( ELbmOwnsItemArray );
       
   831 
       
   832     TInt result = dlg->RunLD();
       
   833     CleanupStack::Pop( textArray );
       
   834 
       
   835     if ( !result )
       
   836         {
       
   837         User::Leave( KErrCancel );
       
   838         }
       
   839     }
       
   840 
       
   841 // -----------------------------------------------------------------------------
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 void CMnAiwProvider::ErrorNote( TInt aResourceId )
       
   845     {
       
   846     TRAP_IGNORE( DoErrorNoteL( aResourceId ) );
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // -----------------------------------------------------------------------------
       
   851 //
       
   852 void CMnAiwProvider::DoErrorNoteL( TInt aResourceId )
       
   853     {
       
   854     HBufC* noteText = iEikon->AllocReadResourceLC( aResourceId );
       
   855 
       
   856     CAknGlobalNote* note = CAknGlobalNote::NewLC();
       
   857     note->ShowNoteL( EAknGlobalErrorNote, *noteText );
       
   858     CleanupStack::PopAndDestroy( note );
       
   859 
       
   860     CleanupStack::PopAndDestroy( noteText );
       
   861     }
       
   862 
       
   863 // ======== GLOBAL FUNCTIONS ========
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // Map the interface UIDs to implementation factory functions
       
   867 // -----------------------------------------------------------------------------
       
   868 //
       
   869 const TImplementationProxy ImplementationTable[] =
       
   870     {
       
   871     IMPLEMENTATION_PROXY_ENTRY( KMnAiwProviderBaseImplUid, CMnAiwProvider::NewL ),
       
   872     IMPLEMENTATION_PROXY_ENTRY( KMnAiwProviderMenuImplUid, CMnAiwProvider::NewL )
       
   873     };
       
   874 
       
   875 // -----------------------------------------------------------------------------
       
   876 // Exported proxy for instantiation method resolution
       
   877 // -----------------------------------------------------------------------------
       
   878 //
       
   879 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
   880     {
       
   881     aTableCount = ( sizeof ImplementationTable ) / sizeof( TImplementationProxy );
       
   882     return ImplementationTable;
       
   883     }