|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** @file |
|
17 @internalComponent */ |
|
18 #include <ecom/ecom.h> |
|
19 #include <ecom/ecomerrorcodes.h> |
|
20 #include <ecom/implementationinformation.h> |
|
21 |
|
22 #include "ImageDisplayResolver.h" |
|
23 #include "ImageDisplayResolvrUtils.h" |
|
24 |
|
25 _LIT(KIclResolverPanicCategory, "ImageDisplayResolver"); |
|
26 |
|
27 // To save some space, we don't support IdentifyImplementationL() |
|
28 |
|
29 GLDEF_C void Panic(TInt aReason) |
|
30 { |
|
31 User::Panic(KIclResolverPanicCategory, aReason); |
|
32 } |
|
33 |
|
34 /** |
|
35 * Constructs and initialises a new instance of CImageDisplayResolver. |
|
36 * |
|
37 * @param "MPublicRegistry& aRegistry" |
|
38 * A reference to the registry on which it will operate |
|
39 * @return "CImageDisplayResolver*" |
|
40 * A pointer to the newly constructed resolver |
|
41 */ |
|
42 CImageDisplayResolver* CImageDisplayResolver::NewL(MPublicRegistry& aRegistry) |
|
43 { |
|
44 return new(ELeave) CImageDisplayResolver(aRegistry); |
|
45 } |
|
46 |
|
47 /** |
|
48 * |
|
49 * Default destructor |
|
50 * |
|
51 */ |
|
52 CImageDisplayResolver::~CImageDisplayResolver() |
|
53 { |
|
54 } |
|
55 |
|
56 /** |
|
57 * |
|
58 * Default constructor |
|
59 * |
|
60 * @param "MPublicRegistry& aRegistry" |
|
61 * A reference to the registry on which it will operate |
|
62 */ |
|
63 CImageDisplayResolver::CImageDisplayResolver(MPublicRegistry& aRegistry) |
|
64 : CResolver(aRegistry) |
|
65 { |
|
66 } |
|
67 |
|
68 /** |
|
69 * |
|
70 * Request that the resolver identify the most appropriate interface |
|
71 * implementation. |
|
72 * |
|
73 * @param "TUid aInterfaceUid" |
|
74 * The Uid of the interface you want to match against |
|
75 * @param "const TEComResolverParams& aAdditionalParameters" |
|
76 * A passed in reference to the parameters on which to match |
|
77 * @return "TUid" |
|
78 * The implementation Uid of the single best match found |
|
79 */ |
|
80 TUid CImageDisplayResolver::IdentifyImplementationL(TUid /*aInterfaceUid*/, const TEComResolverParams& /*aAdditionalParameters*/) const |
|
81 { |
|
82 // To save some space, we don't support IdentifyImplementationL() |
|
83 return KNullUid; |
|
84 } |
|
85 |
|
86 /** |
|
87 * |
|
88 * List all the implementations which satisfy the specified interface, ignoring |
|
89 * any implementations that have their Disabled flag set or are not of the |
|
90 * current framework version. |
|
91 * |
|
92 * The list is sorted: |
|
93 * 1) For EMatchString in desending order of number of bytes matched and version number. |
|
94 * 2) For EMatchMIMEType in asending order of the MIME position that matched and |
|
95 * desending version number. |
|
96 * 3) All others - desending version numbers. |
|
97 * |
|
98 * @param "TUid aInterfaceUid" |
|
99 * The Uid of the interface you want to match against |
|
100 * @param "const TEComResolverParams& aAdditionalParameters" |
|
101 * A passed in reference to the parameters on which to match |
|
102 * @return "RImplInfoArray*" |
|
103 * The list of matches found |
|
104 */ |
|
105 RImplInfoArray* CImageDisplayResolver::ListAllL(TUid aInterfaceUid, const TEComResolverParams& aAdditionalParameters) const |
|
106 { |
|
107 |
|
108 // Retrieve the match data from the descriptor |
|
109 CCustomMatchData* customMatch = CCustomMatchData::NewLC(aAdditionalParameters.DataType()); |
|
110 |
|
111 TResolverMatchType matchType = customMatch->MatchType(); |
|
112 // get the flags that the plugin must support |
|
113 TPluginFlagsNeeded pluginFlagsNeeded = customMatch->PluginFlagsNeeded(); |
|
114 |
|
115 TUid baseType = customMatch->BaseType(); |
|
116 TUid subType = customMatch->SubType(); |
|
117 TUid implementationUid = customMatch->ImplementationType(); |
|
118 HBufC8* matchString = customMatch->MatchString().AllocLC(); |
|
119 HBufC* fileSuffix = customMatch->FileSuffix().AllocLC(); |
|
120 |
|
121 // Use the member var to create the array so that we get proper cleanup behaviour |
|
122 RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid); |
|
123 |
|
124 RArray<TSortImplInfo> sortList; |
|
125 CleanupClosePushL(sortList); |
|
126 |
|
127 TInt matchLevel = 0; |
|
128 |
|
129 // Loop through the implementations matching on appropriate info |
|
130 const TInt count = fullList.Count(); |
|
131 TInt index; |
|
132 |
|
133 for(index = 0; index < count; index++) |
|
134 { |
|
135 const CImplementationInformation& impData = *(fullList[index]); |
|
136 COpaqueDataParse* parse = NULL; |
|
137 TRAPD(error, parse = COpaqueDataParse::NewL(impData.OpaqueData())); |
|
138 if (error!=KErrNone) |
|
139 { |
|
140 if (error==KErrNotSupported) |
|
141 { |
|
142 // means that the resource entry was not valid |
|
143 continue; |
|
144 } |
|
145 else |
|
146 User::Leave(error); |
|
147 } |
|
148 |
|
149 CleanupStack::PushL(parse); |
|
150 |
|
151 // we can assume the version is valid as it is checked in |
|
152 // COpaqueDataParse::ConstructL() which leaves if not valid |
|
153 ASSERT(parse->Version() <= KIclPluginFrameworkVersionMax); |
|
154 |
|
155 // get the plugin's flags |
|
156 TBool flagsSupported = ETrue; |
|
157 if ((pluginFlagsNeeded & ESetSourceRectSupportNeeded) && |
|
158 !parse->IsSetSourceRectSupported()) |
|
159 { |
|
160 flagsSupported = EFalse; |
|
161 } |
|
162 |
|
163 if (!impData.Disabled() && flagsSupported) |
|
164 { |
|
165 TBool matchFound = EFalse; |
|
166 switch(matchType) |
|
167 { |
|
168 case EMatchMIMEType: |
|
169 { |
|
170 if(!parse->OnlyUidsAvail()) |
|
171 { //If codec has no MIME types ignore it |
|
172 parse->EnsureMIMETypesReadL(); |
|
173 const TInt numMimeTypes = parse->MIMETypesCount(); |
|
174 for (TInt index2 = 0; index2 < numMimeTypes; index2++) |
|
175 { |
|
176 const TDesC8& mimeType = parse->MIMEType(index2); |
|
177 if (COpaqueDataParse::CompareMIMETypes(*matchString, mimeType)) |
|
178 { |
|
179 matchFound = ETrue; |
|
180 matchLevel = index2; |
|
181 break; |
|
182 } |
|
183 } |
|
184 } |
|
185 |
|
186 break; |
|
187 } |
|
188 |
|
189 case EMatchString: |
|
190 { // Match the match strings |
|
191 if (CImageDisplayResolverUtils::Match(*matchString, impData.DataType(), matchLevel)) |
|
192 matchFound = ETrue; |
|
193 break; |
|
194 } |
|
195 |
|
196 case EMatchUids: |
|
197 { // match on UIDs |
|
198 if (implementationUid != KNullUid) |
|
199 {// We're matching on codec implementation uid |
|
200 if (implementationUid == impData.ImplementationUid()) |
|
201 matchFound = ETrue; |
|
202 } |
|
203 else |
|
204 { // We're matching on image type (and sub-type) |
|
205 if (parse->CompareUids(baseType, subType)) |
|
206 matchFound = ETrue; |
|
207 } |
|
208 break; |
|
209 } |
|
210 |
|
211 case EMatchFileSuffix: |
|
212 { |
|
213 if(!parse->OnlyUidsAvail() && parse->IsOpenAgainstSuffix()) |
|
214 { //If codec has file extensions and allow matching on them |
|
215 parse->EnsureExtnsReadL(); |
|
216 const TInt numExtns = parse->ExtnsCount(); |
|
217 for (TInt index2 = 0; index2 < numExtns; index2++) |
|
218 { |
|
219 const TDesC8& extn = parse->Extn(index2); |
|
220 if (COpaqueDataParse::CompareFileSuffixL(*fileSuffix, extn)) |
|
221 { |
|
222 matchFound = ETrue; |
|
223 matchLevel = index2; |
|
224 break; |
|
225 } |
|
226 } |
|
227 } |
|
228 |
|
229 break; |
|
230 } |
|
231 |
|
232 default: |
|
233 {//unknown match type |
|
234 Panic(KErrArgument); |
|
235 } |
|
236 } |
|
237 if (matchFound) |
|
238 { |
|
239 TSortImplInfo sortInfo(fullList[index],matchLevel); |
|
240 User::LeaveIfError(sortList.Append(sortInfo)); |
|
241 } |
|
242 } |
|
243 CleanupStack::PopAndDestroy(parse); |
|
244 } |
|
245 |
|
246 TLinearOrder<TSortImplInfo>* sortFunction = NULL; |
|
247 if(matchType==EMatchMIMEType) |
|
248 sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortAsending); |
|
249 else |
|
250 sortFunction = new (ELeave) TLinearOrder<TSortImplInfo>(SortDesending); |
|
251 |
|
252 sortList.Sort(*sortFunction); |
|
253 delete sortFunction; |
|
254 |
|
255 RImplInfoArray* retList = new (ELeave) RImplInfoArray; |
|
256 CleanupStack::PushL(retList); |
|
257 // coverity[double_push] |
|
258 CleanupClosePushL(*retList); // note the double PushL - will Close and delete on PopAndDestroy(2) |
|
259 |
|
260 TInt noEntries = sortList.Count(); |
|
261 for(index = 0; index < noEntries; index++) |
|
262 User::LeaveIfError(retList->Append(sortList[index].iImplInfo)); |
|
263 |
|
264 CleanupStack::Pop(2, retList); // retList x2 |
|
265 |
|
266 CleanupStack::PopAndDestroy(4, customMatch); //sortList, fileSuffix, matchString, customMatch |
|
267 |
|
268 return retList; |
|
269 } |
|
270 |
|
271 /** |
|
272 * Function to sort an array of TSortImplInfo in asending order of the match level and |
|
273 * then in desending order of version numbers. |
|
274 * |
|
275 * @param "const TSortImplInfo& aImpInfo1" |
|
276 * First element. |
|
277 * @param "const TSortImplInfo& aImpInfo2" |
|
278 * Second element. |
|
279 * @return "TInt" |
|
280 * Indication of element swapping order. |
|
281 */ |
|
282 TInt CImageDisplayResolver::SortAsending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2) |
|
283 { |
|
284 TInt result = aImpInfo1.iMatchLevel - aImpInfo2.iMatchLevel; |
|
285 |
|
286 if(result == 0) |
|
287 result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version(); |
|
288 |
|
289 return result; |
|
290 } |
|
291 |
|
292 /** |
|
293 * Function to sort an array of TSortImplInfo in desending order of the match level |
|
294 * and version numbers. |
|
295 * |
|
296 * @param "const TSortImplInfo& aImpInfo1" |
|
297 * First element. |
|
298 * @param "const TSortImplInfo& aImpInfo2" |
|
299 * Second element. |
|
300 * @return "TInt" |
|
301 * Indication of element swapping order. |
|
302 */ |
|
303 TInt CImageDisplayResolver::SortDesending(const TSortImplInfo& aImpInfo1, const TSortImplInfo& aImpInfo2) |
|
304 { |
|
305 TInt result = aImpInfo2.iMatchLevel - aImpInfo1.iMatchLevel; |
|
306 |
|
307 if(result == 0) |
|
308 result = aImpInfo2.iImplInfo->Version() - aImpInfo1.iImplInfo->Version(); |
|
309 |
|
310 return result; |
|
311 } |
|
312 |
|
313 /** |
|
314 * Construtor for the TSortImplInfo class |
|
315 * |
|
316 * @param "CImplementationInformation *const aImplInfo" |
|
317 * A implementation information element to be soreted. |
|
318 * @param "TInt aMatchLevel" |
|
319 * The matching level of the entry |
|
320 */ |
|
321 TSortImplInfo::TSortImplInfo(CImplementationInformation *const aImplInfo, TInt aMatchLevel): |
|
322 iImplInfo(aImplInfo), |
|
323 iMatchLevel(aMatchLevel) |
|
324 { |
|
325 } |
|
326 |