|
1 // Copyright (c) 2006-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 #include <mtp/cmtpstoragemetadata.h> |
|
17 #include <mtp/mmtpconnection.h> |
|
18 #include <mtp/mmtpdataproviderframework.h> |
|
19 #include <mtp/mtpdataproviderapitypes.h> |
|
20 #include <mtp/mtpprotocolconstants.h> |
|
21 #include <ecom/ecom.h> |
|
22 |
|
23 #include "cmtpfiledp.h" |
|
24 #include "cmtpfiledpexclusionmgr.h" |
|
25 #include "cmtpfsenumerator.h" |
|
26 #include "cmtpfiledpconfigmgr.h" |
|
27 #include "cmtprequestprocessor.h" |
|
28 #include "mtpfiledpconst.h" |
|
29 #include "mtpfiledppanic.h" |
|
30 #include "mtpfiledpprocessor.h" |
|
31 |
|
32 // Class constants |
|
33 static const TInt KArrayGranularity = 3; |
|
34 static const TInt KActiveEnumeration = 0; |
|
35 __FLOG_STMT(_LIT8(KComponent,"CMTPFileDataProvider");) |
|
36 |
|
37 /** |
|
38 File data provider factory method. |
|
39 @return A pointer to a file data provider object. Ownership IS transfered. |
|
40 @leave One of the system wide error codes, if a processing failure occurs. |
|
41 */ |
|
42 TAny* CMTPFileDataProvider::NewL(TAny* aParams) |
|
43 { |
|
44 CMTPFileDataProvider* self = new (ELeave) CMTPFileDataProvider(aParams); |
|
45 CleanupStack::PushL(self); |
|
46 self->ConstructL(); |
|
47 CleanupStack::Pop(self); |
|
48 return self; |
|
49 } |
|
50 |
|
51 /** |
|
52 Destructor |
|
53 */ |
|
54 CMTPFileDataProvider::~CMTPFileDataProvider() |
|
55 { |
|
56 __FLOG(_L8("~CMTPFileDataProvider - Entry")); |
|
57 iPendingEnumerations.Close(); |
|
58 TUint count(iActiveProcessors.Count()); |
|
59 while (count--) |
|
60 { |
|
61 iActiveProcessors[count]->Release(); |
|
62 } |
|
63 iActiveProcessors.Close(); |
|
64 iDpSingletons.Close(); |
|
65 iFileDPSingletons.Close(); |
|
66 delete iFileEnumerator; |
|
67 delete iExclusionMgr; |
|
68 __FLOG(_L8("~CMTPFileDataProvider - Exit")); |
|
69 __FLOG_CLOSE; |
|
70 } |
|
71 |
|
72 void CMTPFileDataProvider::Cancel() |
|
73 { |
|
74 __FLOG(_L8("Cancel - Entry")); |
|
75 iFileEnumerator->Cancel(); |
|
76 __FLOG(_L8("Cancel - Exit")); |
|
77 } |
|
78 |
|
79 void CMTPFileDataProvider::ProcessEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection) |
|
80 { |
|
81 __FLOG(_L8("ProcessEventL - Entry")); |
|
82 TInt idx(LocateRequestProcessorL(aEvent, aConnection)); |
|
83 |
|
84 if (idx != KErrNotFound) |
|
85 { |
|
86 iActiveProcessors[idx]->HandleEventL(aEvent); |
|
87 } |
|
88 __FLOG(_L8("ProcessEventL - Exit")); |
|
89 } |
|
90 |
|
91 void CMTPFileDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams) |
|
92 { |
|
93 __FLOG(_L8("ProcessNotificationL - Entry")); |
|
94 switch (aNotification) |
|
95 { |
|
96 case EMTPSessionClosed: |
|
97 SessionClosedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
98 break; |
|
99 |
|
100 case EMTPSessionOpened: |
|
101 SessionOpenedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
102 break; |
|
103 |
|
104 default: |
|
105 // Ignore all other notifications. |
|
106 break; |
|
107 } |
|
108 __FLOG(_L8("ProcessNotificationL - Exit")); |
|
109 } |
|
110 |
|
111 void CMTPFileDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
112 { |
|
113 __FLOG(_L8("ProcessRequestPhaseL - Entry")); |
|
114 TInt idx(LocateRequestProcessorL(aRequest, aConnection)); |
|
115 __ASSERT_DEBUG((idx != KErrNotFound), Panic(EMTPFileDpNoMatchingProcessor)); |
|
116 MMTPRequestProcessor* processor(iActiveProcessors[idx]); |
|
117 iActiveProcessor = idx; |
|
118 iActiveProcessorRemoved = EFalse; |
|
119 TBool result(processor->HandleRequestL(aRequest, aPhase)); |
|
120 if (iActiveProcessorRemoved) |
|
121 { |
|
122 processor->Release(); // destroy the processor |
|
123 } |
|
124 else if (result) |
|
125 { |
|
126 processor->Release(); |
|
127 iActiveProcessors.Remove(idx); |
|
128 } |
|
129 iActiveProcessor = -1; |
|
130 |
|
131 __FLOG(_L8("ProcessRequestPhaseL - Exit")); |
|
132 } |
|
133 |
|
134 void CMTPFileDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/) |
|
135 { |
|
136 __FLOG(_L8("StartObjectEnumerationL - Entry")); |
|
137 |
|
138 iExclusionMgr->AppendFormatExclusionListL(); |
|
139 iDpSingletons.MTPUtility().FormatExtensionMapping(); |
|
140 iPendingEnumerations.AppendL(aStorageId); |
|
141 if (iPendingEnumerations.Count() == 1) |
|
142 { |
|
143 iFileEnumerator->StartL(iPendingEnumerations[KActiveEnumeration]); |
|
144 } |
|
145 __FLOG(_L8("StartObjectEnumerationL - Exit")); |
|
146 } |
|
147 |
|
148 void CMTPFileDataProvider::StartStorageEnumerationL() |
|
149 { |
|
150 __FLOG(_L8("StartStorageEnumerationL - Entry")); |
|
151 Framework().StorageEnumerationCompleteL(); |
|
152 __FLOG(_L8("StartStorageEnumerationL - Exit")); |
|
153 } |
|
154 |
|
155 void CMTPFileDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& aArray) const |
|
156 { |
|
157 __FLOG(_L8("Supported - Entry")); |
|
158 switch (aCategory) |
|
159 { |
|
160 case EEvents: |
|
161 break; |
|
162 |
|
163 case EObjectCaptureFormats: |
|
164 case EObjectPlaybackFormats: |
|
165 aArray.Append(EMTPFormatCodeUndefined); |
|
166 |
|
167 /** |
|
168 * [SP-Format-0x3002]Special processing for PictBridge DP which own 6 dps file with format 0x3002, |
|
169 * but it does not really own the format 0x3002. |
|
170 */ |
|
171 if( PictbridgeDpExistL() ) |
|
172 { |
|
173 aArray.Append(EMTPFormatCodeScript); |
|
174 } |
|
175 break; |
|
176 |
|
177 case EObjectProperties: |
|
178 { |
|
179 TInt count(sizeof(KMTPFileDpSupportedProperties) / sizeof(KMTPFileDpSupportedProperties[0])); |
|
180 for (TInt i(0); (i < count); i++) |
|
181 { |
|
182 aArray.Append(KMTPFileDpSupportedProperties[i]); |
|
183 } |
|
184 } |
|
185 break; |
|
186 |
|
187 case EOperations: |
|
188 { |
|
189 TInt count(sizeof(KMTPFileDpSupportedOperations) / sizeof(KMTPFileDpSupportedOperations[0])); |
|
190 for (TInt i(0); (i < count); i++) |
|
191 { |
|
192 aArray.Append(KMTPFileDpSupportedOperations[i]); |
|
193 } |
|
194 } |
|
195 break; |
|
196 |
|
197 case EStorageSystemTypes: |
|
198 aArray.Append(CMTPStorageMetaData::ESystemTypeDefaultFileSystem); |
|
199 break; |
|
200 |
|
201 default: |
|
202 |
|
203 // Unrecognised category, leave aArray unmodified. |
|
204 break; |
|
205 } |
|
206 __FLOG(_L8("Supported - Exit")); |
|
207 } |
|
208 |
|
209 #ifdef __FLOG_ACTIVE |
|
210 void CMTPFileDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt aError) |
|
211 #else |
|
212 void CMTPFileDataProvider::NotifyEnumerationCompleteL(TUint32 /*aStorageId*/, TInt /*aError*/) |
|
213 #endif // __FLOG_ACTIVE |
|
214 { |
|
215 __FLOG(_L8("HandleEnumerationCompletedL - Entry")); |
|
216 __FLOG_VA((_L8("Enumeration of storage 0x%08X completed with error status %d"), aStorageId, aError)); |
|
217 __ASSERT_DEBUG((aStorageId == iPendingEnumerations[KActiveEnumeration]), User::Invariant()); |
|
218 |
|
219 Framework().ObjectEnumerationCompleteL(iPendingEnumerations[KActiveEnumeration]); |
|
220 iPendingEnumerations.Remove(KActiveEnumeration); |
|
221 if (iPendingEnumerations.Count()) |
|
222 { |
|
223 iFileEnumerator->StartL(iPendingEnumerations[KActiveEnumeration]); |
|
224 } |
|
225 __FLOG(_L8("HandleEnumerationCompletedL - Exit")); |
|
226 } |
|
227 |
|
228 /** |
|
229 Standard C++ constructor |
|
230 */ |
|
231 CMTPFileDataProvider::CMTPFileDataProvider(TAny* aParams) : |
|
232 CMTPDataProviderPlugin(aParams), |
|
233 iActiveProcessors(KArrayGranularity), |
|
234 iPendingEnumerations(KArrayGranularity), |
|
235 iActiveProcessor(-1) |
|
236 { |
|
237 |
|
238 } |
|
239 |
|
240 /** |
|
241 Second-phase constructor. |
|
242 */ |
|
243 void CMTPFileDataProvider::ConstructL() |
|
244 { |
|
245 __FLOG_OPEN(KMTPSubsystem, KComponent); |
|
246 __FLOG(_L8("ConstructL - Entry")); |
|
247 iDpSingletons.OpenL(Framework()); |
|
248 iFileDPSingletons.OpenL(Framework()); |
|
249 |
|
250 iExclusionMgr = CMTPFileDpExclusionMgr::NewL(Framework()); |
|
251 iDpSingletons.SetExclusionMgrL(*iExclusionMgr); |
|
252 |
|
253 TUint processLimit = iFileDPSingletons.FrameworkConfig().UintValueL(CMTPFileDpConfigMgr::EEnumerationIterationLength); |
|
254 iFileEnumerator = CMTPFSEnumerator::NewL(Framework(), iDpSingletons.ExclusionMgrL(), *this, processLimit); |
|
255 __FLOG(_L8("ConstructL - Exit")); |
|
256 } |
|
257 |
|
258 /** |
|
259 Find or create a request processor that can process the specified request. |
|
260 @param aRequest The request to be processed |
|
261 @param aConnection The connection from which the request comes |
|
262 @return the idx of the found/created request processor |
|
263 */ |
|
264 TInt CMTPFileDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
265 { |
|
266 __FLOG(_L8("LocateRequestProcessorL - Entry")); |
|
267 TInt idx(KErrNotFound); |
|
268 TInt count(iActiveProcessors.Count()); |
|
269 for (TInt i(0); (i < count); i++) |
|
270 { |
|
271 if (iActiveProcessors[i]->Match(aRequest, aConnection)) |
|
272 { |
|
273 idx = i; |
|
274 break; |
|
275 } |
|
276 } |
|
277 |
|
278 if (idx == KErrNotFound) |
|
279 { |
|
280 MMTPRequestProcessor* processor = MTPFileDpProcessor::CreateL(Framework(), aRequest, aConnection); |
|
281 CleanupReleasePushL(*processor); |
|
282 iActiveProcessors.AppendL(processor); |
|
283 CleanupStack::Pop(); |
|
284 idx = count; |
|
285 } |
|
286 |
|
287 __FLOG(_L8("LocateRequestProcessorL - Exit")); |
|
288 return idx; |
|
289 } |
|
290 |
|
291 /** |
|
292 Find or create a request processor that can process the specified event. |
|
293 @param aEvent The event to be processed |
|
294 @param aConnection The connection from which the request comes |
|
295 @return the idx of the found request processor, KErrNotFound if not found |
|
296 */ |
|
297 TInt CMTPFileDataProvider::LocateRequestProcessorL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection) |
|
298 { |
|
299 __FLOG(_L8("LocateRequestProcessorL - Entry")); |
|
300 TInt idx(KErrNotFound); |
|
301 TInt count(iActiveProcessors.Count()); |
|
302 for (TInt i(0); (i < count); i++) |
|
303 { |
|
304 if (iActiveProcessors[i]->Match(aEvent, aConnection)) |
|
305 { |
|
306 idx = i; |
|
307 break; |
|
308 } |
|
309 } |
|
310 __FLOG(_L8("LocateRequestProcessorL - Exit")); |
|
311 return idx; |
|
312 } |
|
313 |
|
314 /** |
|
315 Cleans up outstanding request processors when a session is closed. |
|
316 @param aSession notification parameter block |
|
317 */ |
|
318 void CMTPFileDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession) |
|
319 { |
|
320 __FLOG(_L8("SessionClosedL - Entry")); |
|
321 TInt count = iActiveProcessors.Count(); |
|
322 while(count--) |
|
323 { |
|
324 MMTPRequestProcessor* processor = iActiveProcessors[count]; |
|
325 TUint32 sessionId = processor->SessionId(); |
|
326 if((sessionId == aSession.iMTPId) && (processor->Connection().ConnectionId() == aSession.iConnection.ConnectionId())) |
|
327 { |
|
328 iActiveProcessors.Remove(count); |
|
329 if (count == iActiveProcessor) |
|
330 { |
|
331 iActiveProcessorRemoved = ETrue; |
|
332 } |
|
333 else |
|
334 { |
|
335 processor->Release(); |
|
336 } |
|
337 } |
|
338 } |
|
339 __FLOG(_L8("SessionClosedL - Exit")); |
|
340 } |
|
341 |
|
342 /** |
|
343 Prepares for a newly-opened session. |
|
344 @param aSession notification parameter block |
|
345 */ |
|
346 #ifdef __FLOG_ACTIVE |
|
347 void CMTPFileDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& aSession) |
|
348 #else |
|
349 void CMTPFileDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/) |
|
350 #endif |
|
351 { |
|
352 __FLOG(_L8("SessionOpenedL - Entry")); |
|
353 __FLOG_VA((_L8("SessionID = %d"), aSession.iMTPId)); |
|
354 __FLOG(_L8("SessionOpenedL - Exit")); |
|
355 } |
|
356 |
|
357 /** |
|
358 * [SP-Format-0x3002]Special processing for PictBridge DP which own 6 dps file with format 0x3002, |
|
359 * but it does not really own the format 0x3002. |
|
360 * |
|
361 * Check whether the Pictbridgedp exists or not. |
|
362 */ |
|
363 TBool CMTPFileDataProvider::PictbridgeDpExistL() const |
|
364 { |
|
365 __FLOG(_L8("PictbridgeDpExistL - Entry")); |
|
366 |
|
367 RImplInfoPtrArray implementations; |
|
368 TCleanupItem cleanup(ImplementationsCleanup, reinterpret_cast<TAny*>(&implementations)); |
|
369 CleanupStack::PushL(cleanup); |
|
370 REComSession::ListImplementationsL(KMTPDataProviderPluginInterfaceUid, implementations); |
|
371 |
|
372 TBool ret = EFalse; |
|
373 const TUint KUidPictBridge = 0x2001fe3c; |
|
374 TInt count = implementations.Count(); |
|
375 while(--count) |
|
376 { |
|
377 if(implementations[count]->ImplementationUid().iUid == KUidPictBridge) |
|
378 { |
|
379 ret = ETrue; |
|
380 break; |
|
381 } |
|
382 } |
|
383 CleanupStack::PopAndDestroy(&implementations); |
|
384 |
|
385 __FLOG_VA((_L8("return value ret = %d"), ret)); |
|
386 __FLOG(_L8("PictbridgeDpExistL - Exit")); |
|
387 return ret; |
|
388 } |
|
389 |
|
390 /** |
|
391 * [SP-Format-0x3002]Special processing for PictBridge DP which own 6 dps file with format 0x3002, |
|
392 * but it does not really own the format 0x3002. |
|
393 * |
|
394 * Cleanup function |
|
395 */ |
|
396 void CMTPFileDataProvider::ImplementationsCleanup(TAny* aData) |
|
397 { |
|
398 reinterpret_cast<RImplInfoPtrArray*>(aData)->ResetAndDestroy(); |
|
399 } |