|
1 /* |
|
2 * Copyright (c) 2008 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 // System include files |
|
19 #include <ecom/ecom.h> |
|
20 #include <ecom/implementationinformation.h> |
|
21 #include <aknview.h> |
|
22 |
|
23 // User include files |
|
24 #include "xnappuiadapter.h" |
|
25 #include "hscontentcontrolfactory.h" |
|
26 #include "hscontentcontrolecomlistener.h" |
|
27 #include "hscontentcontrolswilistener.h" |
|
28 |
|
29 // Local constants |
|
30 |
|
31 // Content controller ECom interface UID |
|
32 const TUid KInterfaceUidContentController = { 0x20026F51 }; |
|
33 |
|
34 // ======== LOCAL FUNCTIONS ======== |
|
35 |
|
36 // ---------------------------------------------------------------------------- |
|
37 // CleanupResetAndDestroy() |
|
38 // ---------------------------------------------------------------------------- |
|
39 // |
|
40 template<class T> |
|
41 static void CleanupResetAndDestroy( TAny* aObj ) |
|
42 { |
|
43 if( aObj ) |
|
44 { |
|
45 static_cast<T*>( aObj )->ResetAndDestroy(); |
|
46 } |
|
47 } |
|
48 |
|
49 // ---------------------------------------------------------------------------- |
|
50 // CleanupResetAndDestroyPushL |
|
51 // ---------------------------------------------------------------------------- |
|
52 // |
|
53 template<class T> |
|
54 static void CleanupResetAndDestroyPushL(T& aArray) |
|
55 { |
|
56 CleanupStack::PushL( TCleanupItem( &CleanupResetAndDestroy<T>, &aArray ) ); |
|
57 } |
|
58 |
|
59 // ======== MEMBER FUNCTIONS ======== |
|
60 |
|
61 // ---------------------------------------------------------------------------- |
|
62 // CHsContentControlFactory::NewL() |
|
63 // ---------------------------------------------------------------------------- |
|
64 // |
|
65 EXPORT_C CHsContentControlFactory* CHsContentControlFactory::NewL( |
|
66 CXnAppUiAdapter& aAdapter ) |
|
67 { |
|
68 CHsContentControlFactory* self = |
|
69 new ( ELeave ) CHsContentControlFactory( aAdapter ); |
|
70 CleanupStack::PushL( self ); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop( self ); |
|
73 return self; |
|
74 } |
|
75 |
|
76 // ---------------------------------------------------------------------------- |
|
77 // CHsContentControlFactory::ConstructL() |
|
78 // ---------------------------------------------------------------------------- |
|
79 // |
|
80 void CHsContentControlFactory::ConstructL() |
|
81 { |
|
82 iHsContentControlEComListener = |
|
83 CHsContentControlEComListener::NewL( *this ); |
|
84 iHsContentControlSwiListener = |
|
85 CHsContentControlSwiListener::NewL( *this ); |
|
86 |
|
87 REComSession::ListImplementationsL( |
|
88 KInterfaceUidContentController, iImplArray ); |
|
89 } |
|
90 |
|
91 // ---------------------------------------------------------------------------- |
|
92 // CHsContentControlFactory::CHsContentControlFactory() |
|
93 // ---------------------------------------------------------------------------- |
|
94 // |
|
95 CHsContentControlFactory::CHsContentControlFactory( CXnAppUiAdapter& aAdapter ) |
|
96 :iAdapter( aAdapter ) |
|
97 { |
|
98 } |
|
99 |
|
100 // ---------------------------------------------------------------------------- |
|
101 // CHsContentControlFactory::~CHsContentControlFactory() |
|
102 // ---------------------------------------------------------------------------- |
|
103 // |
|
104 EXPORT_C CHsContentControlFactory::~CHsContentControlFactory() |
|
105 { |
|
106 delete iHsContentControlEComListener; |
|
107 delete iHsContentControlSwiListener; |
|
108 |
|
109 iImplArray.ResetAndDestroy(); |
|
110 iImplArray.Close(); |
|
111 |
|
112 iHsContentControlUis.ResetAndDestroy(); |
|
113 } |
|
114 |
|
115 // --------------------------------------------------------------------------------- |
|
116 // CHsContentControlFactory::GetHsContentController() |
|
117 // --------------------------------------------------------------------------------- |
|
118 // |
|
119 EXPORT_C MHsContentControlUi* CHsContentControlFactory::GetHsContentController( |
|
120 const TDesC8& aControlType ) |
|
121 { |
|
122 MHsContentControlUi* retval( FindHsContentController( aControlType ) ); |
|
123 |
|
124 if ( !retval ) |
|
125 { |
|
126 TRAP_IGNORE( |
|
127 // Get implementations via ECom |
|
128 RImplInfoPtrArray plugins; |
|
129 CleanupResetAndDestroyPushL( plugins ); |
|
130 |
|
131 REComSession::ListImplementationsL( |
|
132 KInterfaceUidContentController, plugins ); |
|
133 |
|
134 for ( TInt i = 0; i < plugins.Count(); i++ ) |
|
135 { |
|
136 CImplementationInformation* information( plugins[i] ); |
|
137 |
|
138 if ( information->OpaqueData().CompareF( aControlType ) == 0 ) |
|
139 { |
|
140 CHsContentControlUi* ccUi = CHsContentControlUi::NewL( |
|
141 information->ImplementationUid() ); |
|
142 CleanupStack::PushL( ccUi ); |
|
143 |
|
144 ccUi->SetContentControlTypeL( information->OpaqueData() ); |
|
145 iHsContentControlUis.AppendL( ccUi ); |
|
146 |
|
147 CleanupStack::Pop(); //ccUi |
|
148 retval = ccUi; |
|
149 // All done |
|
150 break; |
|
151 } |
|
152 } |
|
153 |
|
154 CleanupStack::PopAndDestroy(); // plugins |
|
155 ); // TRAP_IGNORE |
|
156 } |
|
157 |
|
158 return retval; |
|
159 } |
|
160 |
|
161 // --------------------------------------------------------------------------------- |
|
162 // CHsContentControlFactory::PrepareToExit() |
|
163 // --------------------------------------------------------------------------------- |
|
164 // |
|
165 EXPORT_C void CHsContentControlFactory::PrepareToExit() |
|
166 { |
|
167 if ( iHsContentControlUis.Count() > 0 ) |
|
168 { |
|
169 for( TInt index( iHsContentControlUis.Count() - 1 ); index >= 0; --index ) |
|
170 { |
|
171 CHsContentControlUi* cc( iHsContentControlUis[ index ] ); |
|
172 ReleaseHsCcUi( cc ); |
|
173 } |
|
174 } |
|
175 } |
|
176 |
|
177 // ---------------------------------------------------------------------------- |
|
178 // CHsContentControlFactory::FindHsContentController() |
|
179 // ---------------------------------------------------------------------------- |
|
180 // |
|
181 MHsContentControlUi* CHsContentControlFactory::FindHsContentController( |
|
182 const TDesC8& aControlType ) |
|
183 { |
|
184 for ( TInt i = 0; i < iHsContentControlUis.Count(); i++ ) |
|
185 { |
|
186 CHsContentControlUi* cc( iHsContentControlUis[ i ] ); |
|
187 |
|
188 if ( cc->ContentControlType().CompareF( aControlType ) == 0 ) |
|
189 { |
|
190 return cc; |
|
191 } |
|
192 } |
|
193 |
|
194 return NULL; |
|
195 } |
|
196 |
|
197 // ---------------------------------------------------------------------------- |
|
198 // CHsContentControlFactory::HandleEComChangeEvent() |
|
199 // ---------------------------------------------------------------------------- |
|
200 // |
|
201 void CHsContentControlFactory::HandleEComChangeEvent() |
|
202 { |
|
203 // ignore event if no plugin loaded. |
|
204 if ( iHsContentControlUis.Count() > 0 ) |
|
205 { |
|
206 TRAP_IGNORE( CheckPluginChangesL(); ); |
|
207 } |
|
208 } |
|
209 |
|
210 // ---------------------------------------------------------------------------- |
|
211 // CHsContentControlFactory::HandleSwiEvent() |
|
212 // ---------------------------------------------------------------------------- |
|
213 // |
|
214 void CHsContentControlFactory::HandleSwiEvent( const RArray<TUid>& aUidList ) |
|
215 { |
|
216 // ignore event if no plugin loaded. |
|
217 if ( iHsContentControlUis.Count() > 0 && aUidList.Count() > 0 ) |
|
218 { |
|
219 for( TInt index( iHsContentControlUis.Count() - 1 ); index >= 0; --index ) |
|
220 { |
|
221 CHsContentControlUi* cc( iHsContentControlUis[ index ] ); |
|
222 for( TInt uidIndex( aUidList.Count() - 1 ); uidIndex >= 0 && cc; --uidIndex ) |
|
223 { |
|
224 // ImplUid of plugin must match Sis pkg uid |
|
225 if ( cc->ImplUid() == aUidList[uidIndex] ) |
|
226 { |
|
227 // release ui and keep checking, multiple package might be being |
|
228 // processed by SWI, this events comes once for all packages. |
|
229 ReleaseHsCcUi( cc ); |
|
230 iHsContentControlUis.Remove( index ); |
|
231 delete cc; |
|
232 cc = NULL; |
|
233 } |
|
234 } |
|
235 } |
|
236 } |
|
237 } |
|
238 |
|
239 // ---------------------------------------------------------------------------- |
|
240 // CHsContentControlFactory::CheckPluginChangesL |
|
241 // ---------------------------------------------------------------------------- |
|
242 // |
|
243 void CHsContentControlFactory::CheckPluginChangesL() |
|
244 { |
|
245 // Array to return all implementations in an interface |
|
246 RImplInfoPtrArray plugInArray; |
|
247 CleanupResetAndDestroyPushL( plugInArray ); |
|
248 |
|
249 // Get the list of all implementations. |
|
250 REComSession::ListImplementationsL( |
|
251 KInterfaceUidContentController, plugInArray ); |
|
252 |
|
253 TUid uid( KNullUid ); |
|
254 TBool done( EFalse ); |
|
255 |
|
256 // If an implementation is not present in present in the plugInArray then its removed. |
|
257 for( TInt index( iImplArray.Count() - 1 ); index >= 0 && !done; --index ) |
|
258 { |
|
259 uid = iImplArray[ index ]->ImplementationUid(); |
|
260 CImplementationInformation* implInfo = |
|
261 FindPluginImplInfo( uid, plugInArray ); |
|
262 if ( implInfo && PluginUpgradeDowngrade( *implInfo ) ) |
|
263 { |
|
264 done = ETrue; |
|
265 } |
|
266 else |
|
267 { |
|
268 // check if ContenControlUi is loaded, unload it |
|
269 for( TInt innerIndex( iHsContentControlUis.Count() - 1 ); |
|
270 innerIndex >= 0 && !done; --innerIndex ) |
|
271 { |
|
272 CHsContentControlUi* cc( iHsContentControlUis[ innerIndex ] ); |
|
273 if ( cc && cc->ImplUid() == uid ) |
|
274 { |
|
275 ReleaseHsCcUi( cc ); |
|
276 iHsContentControlUis.Remove( innerIndex ); |
|
277 delete cc; |
|
278 cc = NULL; |
|
279 done = ETrue; |
|
280 } |
|
281 } |
|
282 done = ETrue; |
|
283 } |
|
284 } |
|
285 |
|
286 // Cleanup. |
|
287 CleanupStack::PopAndDestroy(); // plugInArray |
|
288 |
|
289 // Reset the array and refresh the plugin list. |
|
290 iImplArray.ResetAndDestroy(); |
|
291 iImplArray.Close(); |
|
292 REComSession::ListImplementationsL( |
|
293 KInterfaceUidContentController, iImplArray ); |
|
294 } |
|
295 |
|
296 // ---------------------------------------------------------------------------- |
|
297 // CHsContentControlFactory::FindPluginImplInfo |
|
298 // ---------------------------------------------------------------------------- |
|
299 // |
|
300 CImplementationInformation* CHsContentControlFactory::FindPluginImplInfo( |
|
301 const TUid& aUid, const RImplInfoPtrArray& aPlugInArray ) |
|
302 { |
|
303 CImplementationInformation* implInfo( NULL ); |
|
304 for( TInt index( aPlugInArray.Count() - 1 ); index >= 0; --index ) |
|
305 { |
|
306 implInfo = aPlugInArray[ index ]; |
|
307 if( aUid == implInfo->ImplementationUid() ) |
|
308 { |
|
309 break; |
|
310 } |
|
311 } |
|
312 return implInfo; |
|
313 } |
|
314 |
|
315 // ---------------------------------------------------------------------------- |
|
316 // CHsContentControlFactory::PluginUpgradeDowngrade |
|
317 // ---------------------------------------------------------------------------- |
|
318 // |
|
319 TBool CHsContentControlFactory::PluginUpgradeDowngrade( |
|
320 const CImplementationInformation& aPluginImplInfo ) |
|
321 { |
|
322 // Check for each plugin in the array if the version matches with the plugin we have |
|
323 TUid uid = aPluginImplInfo.ImplementationUid(); |
|
324 for( TInt outterIndex( iImplArray.Count() - 1 ); outterIndex >= 0; --outterIndex ) |
|
325 { |
|
326 if( uid == iImplArray[ outterIndex ]->ImplementationUid() ) |
|
327 { |
|
328 if( aPluginImplInfo.Version() != iImplArray[ outterIndex ]->Version() || |
|
329 aPluginImplInfo.Drive() != iImplArray[ outterIndex ]->Drive() || |
|
330 aPluginImplInfo.DisplayName() != iImplArray[ outterIndex ]->DisplayName() || |
|
331 aPluginImplInfo.OpaqueData() != iImplArray[ outterIndex ]->OpaqueData() ) |
|
332 { |
|
333 // If control reaches here, it means we either have an upgrade or downgrade. |
|
334 // check if we have loaded this plugin, reload it if found in array. |
|
335 for( TInt innerIndex( iHsContentControlUis.Count() - 1 ); |
|
336 innerIndex >= 0; --innerIndex ) |
|
337 { |
|
338 CHsContentControlUi* cc( iHsContentControlUis[ innerIndex ] ); |
|
339 if ( cc && cc->ImplUid() == uid ) |
|
340 { |
|
341 ReleaseHsCcUi( cc ); |
|
342 iHsContentControlUis.Remove( innerIndex ); |
|
343 delete cc; |
|
344 cc = NULL; |
|
345 innerIndex = KErrNotFound; |
|
346 } |
|
347 } |
|
348 return ETrue; |
|
349 } |
|
350 } |
|
351 } |
|
352 return EFalse; |
|
353 } |
|
354 |
|
355 // ---------------------------------------------------------------------------- |
|
356 // CHsContentControlFactory::ReleaseHsCcUi |
|
357 // ---------------------------------------------------------------------------- |
|
358 // |
|
359 void CHsContentControlFactory::ReleaseHsCcUi( |
|
360 CHsContentControlUi* aHsContentControlUi ) |
|
361 { |
|
362 if ( &iAdapter && aHsContentControlUi ) |
|
363 { |
|
364 RPointerArray<CAknView> views; |
|
365 |
|
366 // notify plugin about deactivation |
|
367 aHsContentControlUi->DeActivate(); |
|
368 |
|
369 // get all views from HsContentControlUi |
|
370 aHsContentControlUi->Views( views ); |
|
371 |
|
372 for ( TInt i=0; i<views.Count(); i++ ) |
|
373 { |
|
374 CAknView* view = views[ i ]; |
|
375 views.Remove( i ); |
|
376 // remove/deregister/delete all views from appui |
|
377 TRAP_IGNORE( iAdapter.RemoveViewL( *view ) ); |
|
378 } |
|
379 |
|
380 // reset views array |
|
381 views.Reset(); |
|
382 } |
|
383 } |
|
384 |
|
385 // End of file |