|
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. |