|
1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "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 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDES |
|
22 #include <f32file.h> |
|
23 #include <eikenv.h> |
|
24 #include <bautils.h> |
|
25 #include <utf.h> |
|
26 #include <eikmenup.h> |
|
27 #include <aknutils.h> |
|
28 #include <AknIconUtils.h> |
|
29 #include <AknUtils.h> |
|
30 |
|
31 #include "ImageEditorPluginScanner.h" |
|
32 #include "ImageEditorPluginStorage.h" |
|
33 #include "PluginLoader.h" |
|
34 #include "PluginInfo.h" |
|
35 #include "ImageEditorPluginBaseDefs.h" |
|
36 #include "ImageEditorManagerDef.h" |
|
37 #include "ImageEditorError.h" |
|
38 |
|
39 // PLUGIN TYPE DEFINITIONS |
|
40 #include "plugintypedef.h" |
|
41 |
|
42 // DEBUG LOGGER |
|
43 #include "imageeditordebugutils.h" |
|
44 |
|
45 //============================================================================= |
|
46 CPluginScanner * CPluginScanner::NewL () |
|
47 { |
|
48 CPluginScanner * self = new (ELeave) CPluginScanner; |
|
49 CleanupStack::PushL (self); |
|
50 self->ConstructL (); |
|
51 CleanupStack::Pop(); |
|
52 return self; |
|
53 } |
|
54 |
|
55 //============================================================================= |
|
56 CPluginScanner::~CPluginScanner () |
|
57 { |
|
58 iStorage = NULL; |
|
59 LOG(KImageEditorLogFile, "CPluginScanner: ~CPluginScanner"); |
|
60 } |
|
61 |
|
62 //============================================================================= |
|
63 void CPluginScanner::ScanPluginsL ( TBool& aPluginStorageNeedsUpdate ) |
|
64 { |
|
65 // Check if the plugin storage internalized from disk is |
|
66 // valid. If the plugins have changed, we need to perform |
|
67 // full scan. Otherwise continue with the internalized content. |
|
68 if ( PluginStorageNeedsUpdateL() ) |
|
69 { |
|
70 aPluginStorageNeedsUpdate = ETrue; |
|
71 DoScanPluginsL(); |
|
72 } |
|
73 |
|
74 // Now the plugin infos are almost ready. Only icon bitmaps |
|
75 // are missing... |
|
76 LoadIconBitmapsL(); |
|
77 } |
|
78 |
|
79 //============================================================================= |
|
80 TBool CPluginScanner::PluginStorageNeedsUpdateL () const |
|
81 { |
|
82 LOG(KImageEditorLogFile, "CPluginScanner: Checking for plugin storage validity"); |
|
83 |
|
84 // First check if the plug-in storage is empty, which probably means that |
|
85 // there was no ini file to internalize (could also mean there are no plug-ins...) |
|
86 if ( ! iStorage->CountPlugins() ) |
|
87 { |
|
88 LOG(KImageEditorLogFile, "CPluginScanner: No internalized plugin storage"); |
|
89 return ETrue; |
|
90 } |
|
91 |
|
92 RFs & fs = CEikonEnv::Static()->FsSession(); |
|
93 |
|
94 TInt matchCount = 0; // number of files from the plug-in storage matching with scanned files |
|
95 TInt scanCount = 0; // number of files located from the directory scan |
|
96 |
|
97 // Find all plugins in installation directory |
|
98 TFindFile file_finder (fs); |
|
99 CDir * file_list = 0; |
|
100 |
|
101 TBuf<32> wildCard; |
|
102 wildCard.Append(KResourceWild); |
|
103 |
|
104 TInt err = file_finder.FindWildByDir ( |
|
105 wildCard, |
|
106 KPluginResourcePath, |
|
107 file_list |
|
108 ); |
|
109 |
|
110 // if .RSC file does not found, try to find language specific file |
|
111 if (err) |
|
112 { |
|
113 // Find out what is the current language |
|
114 TFileName resourceFile(KImageEditorResourceFile); |
|
115 |
|
116 CompleteWithAppPath(resourceFile); |
|
117 |
|
118 BaflUtils::NearestLanguageFile(fs, resourceFile); |
|
119 |
|
120 TInt extPosition = resourceFile.LocateReverse(TChar('.')); |
|
121 |
|
122 wildCard.Zero(); |
|
123 wildCard.Append('*'); |
|
124 wildCard.Append(resourceFile.Mid(extPosition)); |
|
125 |
|
126 err = file_finder.FindWildByDir ( |
|
127 wildCard, |
|
128 KPluginResourcePath, |
|
129 file_list |
|
130 ); |
|
131 } |
|
132 |
|
133 // Go through all drives |
|
134 while (err == KErrNone) |
|
135 { |
|
136 CleanupStack::PushL (file_list); |
|
137 scanCount += file_list->Count(); |
|
138 |
|
139 // Check all plug-in candidates |
|
140 for (TInt i = 0; i < file_list->Count(); ++i) |
|
141 { |
|
142 |
|
143 /* |
|
144 * |
|
145 * GET PLUG-IN FILE NAME |
|
146 * |
|
147 */ |
|
148 |
|
149 // Create a full file name for plugin |
|
150 TParse fullentry; |
|
151 TPtrC name = (*file_list)[i].iName; |
|
152 const TDesC* related = &(file_finder.File()); |
|
153 fullentry.Set ( name, related, 0 ); |
|
154 TFileName filename(fullentry.Name()); |
|
155 filename.Append(KPluginExtension); |
|
156 |
|
157 /* |
|
158 * |
|
159 * SEE IF PLUG-IN FILE NAME IS IN THE STORAGE |
|
160 * |
|
161 */ |
|
162 |
|
163 TInt pos; // not used |
|
164 if ( 0 == iStorage->FindPluginDll(filename, pos) ) |
|
165 { |
|
166 matchCount++; |
|
167 } |
|
168 |
|
169 } |
|
170 |
|
171 CleanupStack::PopAndDestroy(); /// file_list |
|
172 |
|
173 // Try once again |
|
174 err = file_finder.FindWild (file_list); |
|
175 } |
|
176 |
|
177 // All plug-in files have been scanned. See the result. |
|
178 if( scanCount == matchCount && matchCount == iStorage->CountPlugins() ) |
|
179 { |
|
180 LOG(KImageEditorLogFile, "CPluginScanner: plug-in storage up to date"); |
|
181 return EFalse; // no update needed |
|
182 } |
|
183 else |
|
184 { |
|
185 LOG(KImageEditorLogFile, "CPluginScanner: plug-in storage update needed"); |
|
186 return ETrue; |
|
187 } |
|
188 } |
|
189 |
|
190 //============================================================================= |
|
191 void CPluginScanner::DoScanPluginsL () |
|
192 { |
|
193 LOG(KImageEditorLogFile, "CPluginScanner: Scanning plugins"); |
|
194 |
|
195 // iStorage may contain invalidated internalized |
|
196 // data, so it needs to be emptied first. |
|
197 iStorage->ResetAndDestroy(); |
|
198 |
|
199 // Create a file session |
|
200 RFs & fs = CEikonEnv::Static()->FsSession(); |
|
201 |
|
202 // Find plugin resource files private directory. It is not allowed |
|
203 // to find plug-in DLLs from /sys/bin/ directory, because of |
|
204 // Platform Security |
|
205 TFindFile file_finder (fs); |
|
206 CDir * file_list = 0; |
|
207 |
|
208 TBuf<32> wildCard; |
|
209 wildCard.Append(KResourceWild); |
|
210 |
|
211 TInt err = file_finder.FindWildByDir ( |
|
212 wildCard, |
|
213 KPluginResourcePath, |
|
214 file_list |
|
215 ); |
|
216 |
|
217 // if .RSC file does not found, try to find language specific file |
|
218 if (err) |
|
219 { |
|
220 // Find out what is the current language |
|
221 TFileName resourceFile(KImageEditorResourceFile); |
|
222 |
|
223 CompleteWithAppPath(resourceFile); |
|
224 |
|
225 BaflUtils::NearestLanguageFile(fs, resourceFile); |
|
226 |
|
227 TInt extPosition = resourceFile.LocateReverse(TChar('.')); |
|
228 |
|
229 wildCard.Zero(); |
|
230 wildCard.Append('*'); |
|
231 wildCard.Append(resourceFile.Mid(extPosition)); |
|
232 |
|
233 err = file_finder.FindWildByDir ( |
|
234 wildCard, |
|
235 KPluginResourcePath, |
|
236 file_list |
|
237 ); |
|
238 } |
|
239 |
|
240 // Go through all drives |
|
241 while (err == KErrNone) |
|
242 { |
|
243 CleanupStack::PushL (file_list); |
|
244 |
|
245 // Check all plug-in candidates |
|
246 for (TInt i = 0; i < file_list->Count(); ++i) |
|
247 { |
|
248 |
|
249 /* |
|
250 * |
|
251 * LOAD PLUG-IN |
|
252 * |
|
253 */ |
|
254 |
|
255 // Create a full file name for plugin |
|
256 TParse fullentry; |
|
257 fullentry.Set ( |
|
258 (*file_list)[i].iName,& |
|
259 file_finder.File(), |
|
260 0 |
|
261 ); |
|
262 |
|
263 // Use resource filename to compose DLL filename |
|
264 TFileName name(fullentry.Name()); |
|
265 name.Append(KPluginExtension); |
|
266 |
|
267 LOGFMT(KImageEditorLogFile,"CPluginScanner: Starting to load plug-in file: %S", &name); |
|
268 |
|
269 // Load plug-in and perform the DLL checks |
|
270 CPluginLoader * pluginloader = |
|
271 CPluginLoader::NewLC (name, &TUid2, 0); |
|
272 |
|
273 |
|
274 // Get pointer to the plugin |
|
275 CPluginType * plugin = pluginloader->GetPlugin(); |
|
276 |
|
277 // Query information and construct CPluginInfo instance |
|
278 CPluginInfo * plugininfo = CPluginInfo::NewLC (); |
|
279 |
|
280 /* |
|
281 * |
|
282 * STORE ALL PLUG-IN INFORMATION |
|
283 * |
|
284 */ |
|
285 |
|
286 // Read buffer and parser |
|
287 TBuf<256> readbuf; |
|
288 TBuf<256> ureadbuf; |
|
289 TLex parser; |
|
290 |
|
291 // PLUG-IN DLL NAME |
|
292 ureadbuf.Copy (name); |
|
293 plugininfo->PluginDll() = ( ureadbuf.AllocL() ); |
|
294 |
|
295 // PLUG-IN UID2 |
|
296 plugininfo->Uid2() = pluginloader->GetPluginDll().Type()[1]; |
|
297 |
|
298 // PLUG-IN UID3 |
|
299 plugininfo->Uid3() = pluginloader->GetPluginDll().Type()[2]; |
|
300 |
|
301 // PLUG-IN UI TYPE |
|
302 User::LeaveIfError ( plugin->GetProperty (KCapPluginUiType, readbuf) ); |
|
303 parser.Assign (readbuf); |
|
304 parser.Val ( plugininfo->PluginUiType() ); |
|
305 |
|
306 // PLUG-IN FILTER TYPE |
|
307 User::LeaveIfError ( plugin->GetProperty (KCapPluginFilterType, readbuf) ); |
|
308 parser.Assign (readbuf); |
|
309 parser.Val ( plugininfo->PluginFilterType() ); |
|
310 |
|
311 // PLUG-IN FILTER SCOPE |
|
312 User::LeaveIfError ( plugin->GetProperty (KCapPluginScope, readbuf) ); |
|
313 parser.Assign (readbuf); |
|
314 parser.Val ( plugininfo->PluginScope() ); |
|
315 |
|
316 // PLUG-IN DISPLAY ORDER VALUE |
|
317 User::LeaveIfError ( plugin->GetProperty (KCapPluginDisplayOrder, readbuf) ); |
|
318 parser.Assign (readbuf); |
|
319 parser.Val ( plugininfo->PluginDisplayOrder() ); |
|
320 |
|
321 // PLUG-IN RUN-TIME ID (RID) |
|
322 plugininfo->PluginRID() = iLastRID++; |
|
323 |
|
324 // PLUG-IN NAME |
|
325 User::LeaveIfError ( plugin->GetProperty (KCapPluginName, readbuf) ); |
|
326 ureadbuf.Copy( readbuf ); |
|
327 plugininfo->PluginName() = ureadbuf.AllocL(); |
|
328 |
|
329 // PLUG-IN ICON FILE NAME |
|
330 User::LeaveIfError ( plugin->GetProperty (KCapIconName, readbuf) ); |
|
331 ureadbuf.Copy( readbuf ); |
|
332 plugininfo->IconFile() = ureadbuf.AllocL(); |
|
333 |
|
334 // PARAMETER DESCRIPTOR ARRAY |
|
335 User::LeaveIfError ( plugin->GetProperty (KCapPluginParamNames, readbuf) ); |
|
336 parser.Assign (readbuf); |
|
337 TInt tempval = 0; |
|
338 parser.Val ( tempval ); |
|
339 CDesCArray * parameters = (CDesCArray *)tempval; |
|
340 if (parameters) |
|
341 { |
|
342 for (TInt j = 0; j < parameters->Count(); ++j) |
|
343 { |
|
344 plugininfo->Parameters().AppendL( (*parameters)[j] ); |
|
345 } |
|
346 } |
|
347 |
|
348 // SOFT KEY 1 COMMAND IDS |
|
349 User::LeaveIfError ( plugin->GetProperty (KCapPluginSk1Cmd, readbuf) ); |
|
350 parser.Assign (readbuf); |
|
351 tempval = 0; |
|
352 parser.Val ( tempval ); |
|
353 CArrayFix<TInt> * cmdids = 0; |
|
354 cmdids = (CArrayFix<TInt> *)tempval; |
|
355 if (cmdids) |
|
356 { |
|
357 for (TInt j = 0; j < cmdids->Count(); ++j) |
|
358 { |
|
359 plugininfo->Sk1Cmds().AppendL( (*cmdids)[j] ); |
|
360 } |
|
361 } |
|
362 |
|
363 // SOFT KEY 1 TEXTS |
|
364 User::LeaveIfError ( plugin->GetProperty (KCapPluginSk1Text, readbuf) ); |
|
365 parser.Assign (readbuf); |
|
366 tempval = 0; |
|
367 parser.Val ( tempval ); |
|
368 CDesCArray * texts = 0; |
|
369 texts = (CDesCArray *)tempval; |
|
370 if (texts) |
|
371 { |
|
372 for (TInt j = 0; j < texts->Count(); ++j) |
|
373 { |
|
374 plugininfo->Sk1Texts().AppendL( (*texts)[j] ); |
|
375 } |
|
376 } |
|
377 |
|
378 // SOFT KEY 2 COMMAND IDS |
|
379 User::LeaveIfError ( plugin->GetProperty (KCapPluginSk2Cmd, readbuf) ); |
|
380 parser.Assign (readbuf); |
|
381 tempval = 0; |
|
382 parser.Val ( tempval ); |
|
383 cmdids = 0; |
|
384 cmdids = (CArrayFix<TInt> *)tempval; |
|
385 if (cmdids) |
|
386 { |
|
387 for (TInt j = 0; j < cmdids->Count(); ++j) |
|
388 { |
|
389 plugininfo->Sk2Cmds().AppendL( (*cmdids)[j] ); |
|
390 } |
|
391 } |
|
392 |
|
393 // SOFT KEY 2 TEXTS |
|
394 User::LeaveIfError ( plugin->GetProperty (KCapPluginSk2Text, readbuf) ); |
|
395 parser.Assign (readbuf); |
|
396 tempval = 0; |
|
397 parser.Val ( tempval ); |
|
398 texts = 0; |
|
399 texts = (CDesCArray *)tempval; |
|
400 if (texts) |
|
401 { |
|
402 for (TInt j = 0; j < texts->Count(); ++j) |
|
403 { |
|
404 plugininfo->Sk2Texts().AppendL( (*texts)[j] ); |
|
405 } |
|
406 } |
|
407 |
|
408 // MSK COMMAND IDS |
|
409 User::LeaveIfError ( plugin->GetProperty (KCapPluginMSKCmd, readbuf) ); |
|
410 parser.Assign (readbuf); |
|
411 tempval = 0; |
|
412 parser.Val ( tempval ); |
|
413 cmdids = 0; |
|
414 cmdids = (CArrayFix<TInt> *)tempval; |
|
415 if (cmdids) |
|
416 { |
|
417 for (TInt j = 0; j < cmdids->Count(); ++j) |
|
418 { |
|
419 plugininfo->MSKCmds().AppendL( (*cmdids)[j] ); |
|
420 } |
|
421 } |
|
422 |
|
423 // MSK TEXTS |
|
424 User::LeaveIfError ( plugin->GetProperty (KCapPluginMSKText, readbuf) ); |
|
425 parser.Assign (readbuf); |
|
426 tempval = 0; |
|
427 parser.Val ( tempval ); |
|
428 texts = 0; |
|
429 texts = (CDesCArray *)tempval; |
|
430 if (texts) |
|
431 { |
|
432 for (TInt j = 0; j < texts->Count(); ++j) |
|
433 { |
|
434 plugininfo->MSKTexts().AppendL( (*texts)[j] ); |
|
435 } |
|
436 } |
|
437 |
|
438 // MENU ITEMS |
|
439 User::LeaveIfError ( plugin->GetProperty (KCapPluginMenuItems, readbuf) ); |
|
440 parser.Assign (readbuf); |
|
441 tempval = 0; |
|
442 parser.Val ( tempval ); |
|
443 CMenuItemArray * menuitems = (CMenuItemArray *)tempval; |
|
444 if (menuitems) |
|
445 { |
|
446 for (TInt j = 0; j < menuitems->Count(); ++j) |
|
447 { |
|
448 plugininfo->MenuItems().AppendL ( (*menuitems)[j] ); |
|
449 } |
|
450 } |
|
451 |
|
452 // Add plugininfo to storage |
|
453 iStorage->AddPluginInfoL (plugininfo); |
|
454 |
|
455 CleanupStack::Pop(); // plugininfo |
|
456 CleanupStack::PopAndDestroy (); // pluginloader |
|
457 } |
|
458 |
|
459 CleanupStack::PopAndDestroy(); /// file_list |
|
460 |
|
461 // Try once again |
|
462 err = file_finder.FindWild (file_list); |
|
463 } |
|
464 } |
|
465 |
|
466 //============================================================================= |
|
467 void CPluginScanner::LoadIconBitmapsL() |
|
468 { |
|
469 ASSERT( iStorage ); |
|
470 |
|
471 for ( TInt i = 0; i < iStorage->CountPlugins(); i++) |
|
472 { |
|
473 CPluginInfo* plugininfo = iStorage->GetPluginInfo(i); |
|
474 |
|
475 TFileName iconfile; |
|
476 iconfile.Copy ( KPluginBitmapPath ); |
|
477 iconfile.Append ( plugininfo->IconFile()->Des() ); |
|
478 |
|
479 CompleteWithAppPath( iconfile ); |
|
480 if ( !BaflUtils::FileExists (CEikonEnv::Static()->FsSession(), iconfile) ) |
|
481 { |
|
482 LOGFMT(KImageEditorLogFile,"CPluginScanner: File not found: %S", &iconfile); |
|
483 User::Leave (KSIEEInternal); |
|
484 } |
|
485 |
|
486 LOGFMT(KImageEditorLogFile,"CPluginScanner: Plug-in icon file: %S", &iconfile); |
|
487 |
|
488 // Check whether icon file is SVG graphic |
|
489 if (AknIconUtils::IsMifFile(iconfile)) |
|
490 { |
|
491 TInt bitmapId = 0; |
|
492 TInt maskId = 0; |
|
493 // Get ids for bitmap and mask |
|
494 // NOTE: ValidateLogicalAppIconId returns same id for both! |
|
495 AknIconUtils::ValidateLogicalAppIconId(iconfile, bitmapId, maskId); |
|
496 AknIconUtils::CreateIconL( |
|
497 plugininfo->Icon(), |
|
498 plugininfo->Mask(), |
|
499 iconfile, |
|
500 bitmapId, |
|
501 maskId+1); // TEMPORARY FIX |
|
502 |
|
503 //plugininfo->Icon()->Save(_L("icon.mbm")); |
|
504 //plugininfo->Mask()->Save(_L("mask.mbm")); |
|
505 } |
|
506 else |
|
507 { |
|
508 // PLUG-IN ICON BITMAP |
|
509 CFbsBitmap * icon = new (ELeave) CFbsBitmap; |
|
510 CleanupStack::PushL (icon); |
|
511 User::LeaveIfError ( icon->Load (iconfile, 0) ); |
|
512 plugininfo->Icon() = icon; |
|
513 CleanupStack::Pop(); // icon |
|
514 |
|
515 // PLUG-IN MASK BITMAP |
|
516 CFbsBitmap * mask = new (ELeave) CFbsBitmap; |
|
517 CleanupStack::PushL (mask); |
|
518 User::LeaveIfError ( mask->Load (iconfile, 1) ); |
|
519 plugininfo->Mask() = mask; |
|
520 CleanupStack::Pop(); // mask |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 //============================================================================= |
|
526 CPluginScanner::CPluginScanner() |
|
527 { |
|
528 |
|
529 } |
|
530 |
|
531 //============================================================================= |
|
532 void CPluginScanner::ConstructL () |
|
533 { |
|
534 |
|
535 } |
|
536 |
|
537 // End of File |