emailservices/emailclientapi/src/emailclientapiimpl.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2009 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: This file implements class CEmailClientApi.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <viewclipartner.h>
       
    22 #include <vwsdefpartner.h>
       
    23 #else
       
    24 #include <viewcli.h>
       
    25 #include <vwsdef.h>
       
    26 #endif // SYMBIAN_ENABLE_SPLIT_HEADERS
       
    27 
       
    28 #include "emailclientapiimpl.h"
       
    29 #include "emailapiutils.h"
       
    30 #include "emailmailbox.h"
       
    31 #include <memailaddress.h>
       
    32 #include "CFSMailPlugin.h"
       
    33 #include "CFSClientAPI.h"
       
    34 #include "emailclientapiimpldefs.h"
       
    35 #include "emailmailboxcache.h"
       
    36 #include "FreestyleEmailUiConstants.h"
       
    37 #include "emailclientapi.hrh"
       
    38 // ---------------------------------------------------------------------------
       
    39 // CEmailClientApi::MailboxL
       
    40 // ---------------------------------------------------------------------------
       
    41 //
       
    42 MEmailMailbox* CEmailClientApi::MailboxL( const TMailboxId& aId )
       
    43     {
       
    44     UpdateMailboxInfoCacheL();
       
    45     CPluginData* pluginData = MailboxInfoCacheL().PluginDataL( aId );
       
    46     MEmailMailbox* mailbox = NULL;
       
    47     if ( pluginData )
       
    48         {
       
    49         mailbox = CEmailMailbox::NewL( *pluginData, aId );
       
    50         }
       
    51     return mailbox;
       
    52     }
       
    53 
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // 
       
    57 // -----------------------------------------------------------------------------
       
    58 MEmailMailbox* CEmailClientApi::MailboxL( const TPtrC& aAddress )
       
    59     {
       
    60     MEmailMailbox* mailbox = NULL;
       
    61     REmailMailboxIdArray mailboxes;
       
    62     CleanupClosePushL( mailboxes );
       
    63     TInt count( GetMailboxIdsL( mailboxes ) );
       
    64     while ( count-- )
       
    65         {
       
    66         const TMailboxId mailboxId = mailboxes[count];
       
    67         MEmailMailbox* refMailbox = MailboxL( mailboxId );
       
    68         if ( refMailbox )
       
    69             {
       
    70             TPtrC address( refMailbox->AddressL()->Address() );
       
    71             if ( !address.Compare( aAddress ) )
       
    72                 {
       
    73                 mailbox = refMailbox; // addresses match
       
    74                 count = 0;
       
    75                 }
       
    76             else
       
    77                 {
       
    78                 refMailbox->Release();
       
    79                 }
       
    80             }
       
    81         }
       
    82     CleanupStack::PopAndDestroy();
       
    83     // find mailbox or leave KErrNotFound
       
    84     if ( !mailbox)
       
    85         {
       
    86         User::Leave( KErrNotFound );
       
    87         }
       
    88     return mailbox;
       
    89     }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // 
       
    93 // -----------------------------------------------------------------------------
       
    94 TInt CEmailClientApi::GetMailboxIdsL( 
       
    95     REmailMailboxIdArray& aMailboxes )
       
    96     {
       
    97     UpdateMailboxInfoCacheL();
       
    98 
       
    99     aMailboxes.Reset();
       
   100     CEmailMailboxCache& mbcache = MailboxInfoCacheL();
       
   101     mbcache.GetIdsL( aMailboxes ); 
       
   102 
       
   103     const TInt mailboxesFound( aMailboxes.Count() );
       
   104     return mailboxesFound;
       
   105     }
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // 
       
   109 // -----------------------------------------------------------------------------
       
   110 TInt CEmailClientApi::GetMailboxesL( RMailboxPtrArray& aMailboxes )
       
   111     {
       
   112     REmailMailboxIdArray mailboxIdArray;
       
   113     CleanupClosePushL( mailboxIdArray );
       
   114     
       
   115     // note! GetMailboxIdsL loads plugin and keeps loaded if it contains at
       
   116     // least one mailbox
       
   117     TInt count = GetMailboxIdsL( mailboxIdArray );
       
   118     while ( count-- )
       
   119         {
       
   120         // mailbox creation increases plugin ref count by one
       
   121         MEmailMailbox* mailbox = MailboxL( mailboxIdArray[count] );
       
   122         CleanupReleasePushL( *mailbox );
       
   123         aMailboxes.AppendL( mailbox );
       
   124         CleanupStack::Pop( mailbox );
       
   125         }
       
   126     // Created mailboxes still hold plugin references so we can decrease 
       
   127     // ref count.
       
   128     ReleaseAllPlugins(); 
       
   129     
       
   130     CleanupStack::PopAndDestroy(); // mailboxIdArray
       
   131     return aMailboxes.Count();
       
   132     }
       
   133 
       
   134 // -----------------------------------------------------------------------------
       
   135 // implement this
       
   136 // -----------------------------------------------------------------------------
       
   137 void CEmailClientApi::LaunchEmailL( const TLaunchPolicy aPolicy )
       
   138     {
       
   139     if ( aPolicy != EDefault )
       
   140         {
       
   141         // no other launch policies supported
       
   142         User::Leave( KErrNotSupported );
       
   143         }
       
   144     const TUid dummy = {0};
       
   145                 
       
   146     CVwsSessionWrapper* viewSrvSession = CVwsSessionWrapper::NewLC();
       
   147     viewSrvSession->ActivateView(TVwsViewId(KFSEmailUiUid, AppGridId),
       
   148         dummy, KNullDesC8() );
       
   149     CleanupStack::PopAndDestroy();    
       
   150     }    
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // 
       
   154 // -----------------------------------------------------------------------------
       
   155 CPluginData* CEmailClientApi::TPluginIterator::Next()
       
   156     {
       
   157     CPluginData* item = NULL;
       
   158     if ( iIndex < iArray.Count() )
       
   159         {
       
   160         item = iArray[ iIndex++ ];
       
   161         }
       
   162     return item;
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // 
       
   167 // -----------------------------------------------------------------------------
       
   168 CEmailClientApi* CEmailClientApi::NewL()
       
   169     {
       
   170     CEmailClientApi* self = new ( ELeave ) CEmailClientApi();
       
   171     CleanupStack::PushL( self );
       
   172     self->ConstructL();
       
   173     CleanupStack::Pop();
       
   174     return self;
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // 
       
   179 // -----------------------------------------------------------------------------
       
   180 CEmailClientApi::~CEmailClientApi()
       
   181     {
       
   182     // ensure this doesn't held plugin references
       
   183     ReleaseAllPlugins();
       
   184 
       
   185     // ResetAndDestroy doesn't work because ~CPluginData is private
       
   186     TInt count( iPluginDataArray.Count() );
       
   187     while ( count-- )
       
   188         {
       
   189         delete iPluginDataArray[count];
       
   190         }
       
   191     iPluginDataArray.Close();
       
   192     iLoadedPluginsArray.Close();
       
   193     delete iMailboxCache;
       
   194     delete iClientAPI;
       
   195     }
       
   196 
       
   197 // -----------------------------------------------------------------------------
       
   198 // 
       
   199 // -----------------------------------------------------------------------------
       
   200 CEmailClientApi::CEmailClientApi()
       
   201     {        
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // 
       
   206 // -----------------------------------------------------------------------------
       
   207 void CEmailClientApi::CleanupImplInfoPushL( RPointerArray<CImplementationInformation>& aArray )
       
   208     {
       
   209     TCleanupItem item( &CEmailClientApi::CleanupImplInfo, &aArray );
       
   210     CleanupStack::PushL( item );
       
   211     }
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // 
       
   215 // -----------------------------------------------------------------------------
       
   216 void CEmailClientApi::CleanupImplInfo( TAny* aAny )
       
   217     {
       
   218     RPointerArray<CImplementationInformation>* array = 
       
   219         reinterpret_cast<RPointerArray<CImplementationInformation>*>( aAny );
       
   220     array->ResetAndDestroy();
       
   221     }
       
   222  
       
   223 // -----------------------------------------------------------------------------
       
   224 // 
       
   225 // -----------------------------------------------------------------------------
       
   226 void CEmailClientApi::ConstructL()
       
   227     {
       
   228     RPointerArray<CImplementationInformation> implInfoArray;
       
   229     REComSession::ListImplementationsL( KFSMailPluginInterface, implInfoArray );
       
   230     CleanupImplInfoPushL( implInfoArray );
       
   231     TInt err = KErrNone;
       
   232     TInt count( implInfoArray.Count() );
       
   233     // add implementation UIDs to plugin info array, no instantiation at this
       
   234     // phase
       
   235     while ( count-- )
       
   236         {
       
   237         const CImplementationInformation* info = implInfoArray[count];
       
   238         CPluginData* pluginData = new ( ELeave ) CPluginData( info->ImplementationUid() );
       
   239         err = iPluginDataArray.Append( pluginData );
       
   240         if ( err != KErrNone )
       
   241             {
       
   242             // failed to append, give up
       
   243             delete pluginData;
       
   244             count = 0;
       
   245             }
       
   246         }
       
   247     iClientAPI = CFSClientAPI::NewL(this);
       
   248     CleanupStack::PopAndDestroy(); // CleanupImplInfoPushL
       
   249     User::LeaveIfError( err );    
       
   250     }
       
   251 
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // 
       
   255 // -----------------------------------------------------------------------------
       
   256 TEmailTypeId CEmailClientApi::InterfaceId() const
       
   257     {
       
   258     return KEmailClientApiInterface;
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // 
       
   263 // -----------------------------------------------------------------------------
       
   264 void CEmailClientApi::Release()
       
   265     {
       
   266     delete this;
       
   267     }
       
   268        
       
   269 // -----------------------------------------------------------------------------
       
   270 // Returns plugin instance from plugin data. If we already have "claimed"
       
   271 // instance once, prevent increment of reference count 
       
   272 // -----------------------------------------------------------------------------
       
   273 CFSMailPlugin* CEmailClientApi::UsePlugin( CPluginData& aPluginData )
       
   274     {
       
   275     // use 'data' as search key for IndexOfLoadedPluginData()
       
   276     TPluginData data( aPluginData.Uid() );
       
   277     TPluginData* pluginDataPtr = &data;
       
   278     // check if we have plugin already "in use".
       
   279     const TInt index( IndexOfLoadedPluginData( data ) );
       
   280     if ( index == KErrNotFound )
       
   281         { // we don't have plugin instance so take it and add to loaded plugins
       
   282         data.iPlugin = aPluginData.ClaimInstance();
       
   283         if ( data.iPlugin && iLoadedPluginsArray.Append( data ) != KErrNone )
       
   284             {                
       
   285             aPluginData.ReleaseInstance(); // failed to append, don't proceed..
       
   286             data.iPlugin = NULL;           // but return null
       
   287             }          
       
   288         }
       
   289     else
       
   290         {
       
   291         // already in use, obtain plugin pointer from the array
       
   292         pluginDataPtr = &iLoadedPluginsArray[index];
       
   293         }
       
   294     return pluginDataPtr->iPlugin;
       
   295     }
       
   296     
       
   297 // -----------------------------------------------------------------------------
       
   298 // 
       
   299 // -----------------------------------------------------------------------------
       
   300 void CEmailClientApi::ReleasePlugin( CPluginData& aPluginData )
       
   301     {
       
   302     // release plugin but only if it is not already claimed
       
   303     TPluginData data( aPluginData.Uid() );
       
   304     const TInt index( IndexOfLoadedPluginData( data ) );
       
   305      if ( index != KErrNotFound )
       
   306         {
       
   307         aPluginData.ReleaseInstance();
       
   308         iLoadedPluginsArray.Remove( index );
       
   309         }
       
   310     }
       
   311 
       
   312 // -----------------------------------------------------------------------------
       
   313 // 
       
   314 // -----------------------------------------------------------------------------
       
   315 void CEmailClientApi::ReleaseAllPlugins()
       
   316     {
       
   317     for ( TInt i = 0; i < iPluginDataArray.Count(); i++ )
       
   318         {
       
   319         CPluginData* pdata = iPluginDataArray[i];
       
   320         ReleasePlugin( *pdata );
       
   321         }
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // 
       
   326 // -----------------------------------------------------------------------------
       
   327 CEmailMailboxCache& CEmailClientApi::MailboxInfoCacheL()
       
   328     {
       
   329     if ( !iMailboxCache) 
       
   330         {
       
   331         iMailboxCache = CEmailMailboxCache::NewL();
       
   332         }
       
   333     return *iMailboxCache;
       
   334     }
       
   335 
       
   336 // -----------------------------------------------------------------------------
       
   337 // Lists all mailboxes in protocol plugins and adds them to cache. Plugins may 
       
   338 // not be loaded so loading is done. The plugin is kept in memory if it contains
       
   339 // at least one mailbox to avoid loading again later as typical use case is 
       
   340 // creation of a mailbox object => the plugin is again needed 
       
   341 //( see ::GetMailboxesL which calls ReleaseAllPlugins()
       
   342 // -----------------------------------------------------------------------------
       
   343 void CEmailClientApi::UpdateMailboxInfoCacheL()
       
   344     {
       
   345     CEmailMailboxCache& mbcache = MailboxInfoCacheL();
       
   346     if ( !mbcache.IsCached() )
       
   347         {
       
   348         // cache update needed
       
   349         mbcache.StartCachingPushL();
       
   350         TPluginIterator iter( iPluginDataArray );
       
   351         CPluginData* pluginData = iter.Next();
       
   352         while ( pluginData )
       
   353             {
       
   354             TBool containsMailbox( EFalse );
       
   355             // loads plugin if needed
       
   356             CFSMailPlugin* plugin = UsePlugin( *pluginData );
       
   357             if ( plugin )
       
   358                 {
       
   359                 // if one plugin fails, it should not block other plugins
       
   360                 // ==> trap it             
       
   361                 
       
   362                 TRAPD( err, containsMailbox = CachePluginMailboxesL(
       
   363                     *pluginData, 
       
   364                     *plugin ) );
       
   365                 if ( !containsMailbox || err )
       
   366                     {
       
   367                     // plugins with no mailboxes (or failed to cache) is
       
   368                     // released (unloaded) to optimize RAM usage.
       
   369                     ReleasePlugin( *pluginData );
       
   370                     }            
       
   371                 }
       
   372             else if ( pluginData->iPluginLoadError == KErrNoMemory )
       
   373                 {
       
   374                 // don't continue if OOM
       
   375                 User::Leave( KErrNoMemory );
       
   376                 }
       
   377             pluginData = iter.Next();
       
   378             }
       
   379         mbcache.EndCachingPop();    
       
   380         }    
       
   381     }
       
   382 
       
   383 // -----------------------------------------------------------------------------
       
   384 // 
       
   385 // -----------------------------------------------------------------------------
       
   386 TBool CEmailClientApi::CachePluginMailboxesL( CPluginData& aPluginData, CFSMailPlugin& aPlugin )
       
   387     {
       
   388     TBool containsMailbox( EFalse );
       
   389     RArray<TFSMailMsgId> pluginMailboxes;
       
   390     CleanupClosePushL( pluginMailboxes );
       
   391     aPlugin.ListMailBoxesL( pluginMailboxes );
       
   392     TInt mailboxCount = pluginMailboxes.Count();
       
   393     while ( mailboxCount-- )
       
   394         {
       
   395         const TFSMailMsgId& mailboxId = pluginMailboxes[mailboxCount];
       
   396         TMailboxId id( mailboxId.Id() );                    
       
   397         MailboxInfoCacheL().AddMailboxL( aPluginData, id );
       
   398         containsMailbox = ETrue;
       
   399         }
       
   400     CleanupStack::PopAndDestroy();  // pluginMailboxes
       
   401     return containsMailbox;
       
   402     }
       
   403 
       
   404 // -----------------------------------------------------------------------------
       
   405 // 
       
   406 // -----------------------------------------------------------------------------
       
   407 TInt CEmailClientApi::IndexOfLoadedPluginData( const TPluginData& aPluginData ) const
       
   408     {
       
   409     TIdentityRelation<TPluginData> relation( CEmailClientApi::PluginDataEquals );    
       
   410     return iLoadedPluginsArray.Find( aPluginData, relation );
       
   411     }
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 // 
       
   415 // -----------------------------------------------------------------------------
       
   416 TBool CEmailClientApi::PluginDataEquals( const TPluginData& a1, const TPluginData& a2 )
       
   417     {
       
   418     return ( a1.iUid == a2.iUid );
       
   419     }
       
   420 
       
   421 CFSMailPlugin* CEmailClientApi::GetPluginByUid(TUid aUid)
       
   422     {
       
   423     CPluginData *p = NULL;
       
   424     CFSMailPlugin* plugin = NULL;
       
   425 
       
   426     TRAP_IGNORE( p = iMailboxCache->PluginDataL(aUid) );
       
   427     if ( p )
       
   428         {
       
   429         plugin = p->ClaimInstance();       
       
   430         p->ReleaseInstance();
       
   431         }
       
   432     return plugin;
       
   433     }
       
   434 
       
   435 // End of file.