|
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/tmtptyperequest.h> |
|
21 |
|
22 #include "cmtpdevdpexclusionmgr.h" |
|
23 #include "cmtpdevicedatastore.h" |
|
24 #include "cmtpdevicedp.h" |
|
25 #include "cmtpdevicedpconfigmgr.h" |
|
26 #include "cmtpfsenumerator.h" |
|
27 #include "cmtprequestprocessor.h" |
|
28 #include "cmtpstoragewatcher.h" |
|
29 #include "mtpdevicedpconst.h" |
|
30 #include "mtpdevicedpprocessor.h" |
|
31 #include "mtpdevdppanic.h" |
|
32 |
|
33 #include "cmtpextndevdp.h" |
|
34 #include <mtp/cmtptypestring.h> |
|
35 |
|
36 |
|
37 // Class constants. |
|
38 __FLOG_STMT(_LIT8(KComponent,"DeviceDataProvider");) |
|
39 static const TInt KMTPDeviceDpSessionGranularity(3); |
|
40 static const TInt KMTPDeviceDpActiveEnumeration(0); |
|
41 |
|
42 /** |
|
43 MTP device data provider plug-in factory method. |
|
44 @return A pointer to an MTP device data provider plug-in. Ownership IS |
|
45 transfered. |
|
46 @leave One of the system wide error codes, if a processing failure occurs. |
|
47 */ |
|
48 TAny* CMTPDeviceDataProvider::NewL(TAny* aParams) |
|
49 { |
|
50 CMTPDeviceDataProvider* self = new (ELeave) CMTPDeviceDataProvider(aParams); |
|
51 CleanupStack::PushL(self); |
|
52 self->ConstructL(); |
|
53 CleanupStack::Pop(self); |
|
54 return self; |
|
55 } |
|
56 |
|
57 /** |
|
58 Destructor |
|
59 */ |
|
60 CMTPDeviceDataProvider::~CMTPDeviceDataProvider() |
|
61 { |
|
62 __FLOG(_L8("~CMTPDeviceDataProvider - Entry")); |
|
63 iPendingEnumerations.Close(); |
|
64 TInt count = iActiveProcessors.Count(); |
|
65 while(count--) |
|
66 { |
|
67 iActiveProcessors[count]->Release(); |
|
68 } |
|
69 iActiveProcessors.Close(); |
|
70 delete iStorageWatcher; |
|
71 iDevDpSingletons.Close(); |
|
72 iDpSingletons.Close(); |
|
73 delete iEnumerator; |
|
74 delete iExclusionMgr; |
|
75 |
|
76 iExtnPluginMapArray.ResetAndDestroy(); |
|
77 iExtnPluginMapArray.Close(); |
|
78 iEvent.Reset(); |
|
79 |
|
80 __FLOG(_L8("~CMTPDeviceDataProvider - Exit")); |
|
81 __FLOG_CLOSE; |
|
82 } |
|
83 |
|
84 void CMTPDeviceDataProvider::Cancel() |
|
85 { |
|
86 |
|
87 } |
|
88 |
|
89 void CMTPDeviceDataProvider::ProcessEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection) |
|
90 { |
|
91 __FLOG(_L8("ProcessEventL - Entry")); |
|
92 TInt index = LocateRequestProcessorL(aEvent, aConnection); |
|
93 if(index != KErrNotFound) |
|
94 { |
|
95 iActiveProcessors[index]->HandleEventL(aEvent); |
|
96 } |
|
97 __FLOG(_L8("ProcessEventL - Exit")); |
|
98 } |
|
99 |
|
100 void CMTPDeviceDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams) |
|
101 { |
|
102 __FLOG(_L8("ProcessNotificationL - Entry")); |
|
103 switch (aNotification) |
|
104 { |
|
105 case EMTPSessionClosed: |
|
106 SessionClosedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
107 break; |
|
108 |
|
109 case EMTPSessionOpened: |
|
110 SessionOpenedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
111 break; |
|
112 |
|
113 default: |
|
114 // Ignore all other notifications. |
|
115 break; |
|
116 } |
|
117 __FLOG(_L8("ProcessNotificationL - Exit")); |
|
118 } |
|
119 |
|
120 void CMTPDeviceDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
121 { |
|
122 __FLOG(_L8("ProcessRequestPhaseL - Entry")); |
|
123 TInt index = LocateRequestProcessorL(aRequest, aConnection); |
|
124 __ASSERT_DEBUG(index != KErrNotFound, Panic(EMTPDevDpNoMatchingProcessor)); |
|
125 MMTPRequestProcessor* processor = iActiveProcessors[index]; |
|
126 iActiveProcessor = index; |
|
127 iActiveProcessorRemoved = EFalse; |
|
128 TBool result = processor->HandleRequestL(aRequest, aPhase); |
|
129 if (iActiveProcessorRemoved) |
|
130 { |
|
131 processor->Release(); // destroy the processor |
|
132 } |
|
133 else if (result) |
|
134 { |
|
135 processor->Release(); |
|
136 iActiveProcessors.Remove(index); |
|
137 } |
|
138 iActiveProcessor = -1; |
|
139 __FLOG(_L8("ProcessRequestPhaseL - Exit")); |
|
140 } |
|
141 |
|
142 void CMTPDeviceDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/) |
|
143 { |
|
144 __FLOG(_L8("StartObjectEnumerationL - Entry")); |
|
145 iPendingEnumerations.AppendL(aStorageId); |
|
146 if (iEnumeratingState == EUndefined) |
|
147 { |
|
148 iDevDpSingletons.DeviceDataStore().StartEnumerationL(aStorageId, *this); |
|
149 iEnumeratingState = EEnumeratingDeviceDataStore; |
|
150 iStorageWatcher->Start(); |
|
151 } |
|
152 else if (iPendingEnumerations.Count() == 1) |
|
153 { |
|
154 iEnumeratingState = EEnumeratingFolders; |
|
155 iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]); |
|
156 } |
|
157 __FLOG(_L8("StartObjectEnumerationL - Exit")); |
|
158 } |
|
159 |
|
160 void CMTPDeviceDataProvider::StartStorageEnumerationL() |
|
161 { |
|
162 __FLOG(_L8("StartStorageEnumerationL - Entry")); |
|
163 iStorageWatcher->EnumerateStoragesL(); |
|
164 Framework().StorageEnumerationCompleteL(); |
|
165 __FLOG(_L8("StartStorageEnumerationL - Exit")); |
|
166 } |
|
167 |
|
168 void CMTPDeviceDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& aArray) const |
|
169 { |
|
170 __FLOG(_L8("Supported - Entry")); |
|
171 TInt mode = Framework().Mode(); |
|
172 switch (aCategory) |
|
173 { |
|
174 case EAssociationTypes: |
|
175 aArray.Append(EMTPAssociationTypeGenericFolder); |
|
176 break; |
|
177 |
|
178 case EDeviceProperties: |
|
179 { |
|
180 TInt count = sizeof(KMTPDeviceDpSupportedProperties) / sizeof(TUint16); |
|
181 for(TInt i = 0; i < count; i++) |
|
182 { |
|
183 if(( (EModePTP == mode) ||(EModePictBridge == mode) ) |
|
184 && ( 0x4000 == (KMTPDeviceDpSupportedProperties[i] & 0xE000))) |
|
185 { |
|
186 //in ptp mode support only ptp properties |
|
187 aArray.Append(KMTPDeviceDpSupportedProperties[i]); |
|
188 } |
|
189 else |
|
190 { |
|
191 aArray.Append(KMTPDeviceDpSupportedProperties[i]); |
|
192 } |
|
193 } |
|
194 |
|
195 TInt noOfEtxnPlugins = iExtnPluginMapArray.Count(); |
|
196 for(TInt i=0; i < noOfEtxnPlugins; i++) |
|
197 { |
|
198 iExtnPluginMapArray[i]->ExtPlugin()->Supported(aCategory, *iExtnPluginMapArray[i]->SupportedOpCodes(), (TMTPOperationalMode)mode );// or pass the incoming array |
|
199 TInt count =iExtnPluginMapArray[i]->SupportedOpCodes()->Count(); |
|
200 //bcoz it needs to b updated |
|
201 for (TInt r=0; r <count; r++ ) |
|
202 { |
|
203 aArray.Append((*iExtnPluginMapArray[i]->SupportedOpCodes())[r]); |
|
204 } |
|
205 } |
|
206 |
|
207 TRAP_IGNORE(iPtrDataStore->SetSupportedDevicePropertiesL(aArray)); |
|
208 } |
|
209 break; |
|
210 |
|
211 case EEvents: |
|
212 { |
|
213 TInt count = sizeof(KMTPDeviceDpSupportedEvents) / sizeof(TUint16); |
|
214 for(TInt i = 0; i < count; i++) |
|
215 { |
|
216 TUint16 event = KMTPDeviceDpSupportedEvents[i]; |
|
217 switch(mode) |
|
218 { |
|
219 case EModePTP: |
|
220 case EModePictBridge: |
|
221 // In the initial implementation all device DP events pass this test, but this |
|
222 // catches any others added in the future that fall outside this range. |
|
223 if(event <= EMTPEventCodePTPEnd) |
|
224 { |
|
225 aArray.Append(event); |
|
226 } |
|
227 break; |
|
228 |
|
229 case EModeMTP: |
|
230 // In the initial implementation all device DP events pass this test, but this |
|
231 // catches any others added in the future that fall outside this range. |
|
232 if(event <= EMTPEventCodeMTPEnd) |
|
233 { |
|
234 aArray.Append(event); |
|
235 } |
|
236 break; |
|
237 |
|
238 default: |
|
239 // No other valid modes are defined |
|
240 break; |
|
241 } |
|
242 } |
|
243 } |
|
244 break; |
|
245 |
|
246 case EObjectCaptureFormats: |
|
247 case EObjectPlaybackFormats: |
|
248 // Only supports association objects |
|
249 aArray.Append(EMTPFormatCodeAssociation); |
|
250 break; |
|
251 |
|
252 |
|
253 case EOperations: |
|
254 { |
|
255 TInt count = sizeof(KMTPDeviceDpSupportedOperations) / sizeof(TUint16); |
|
256 for(TInt i = 0; i < count; i++) |
|
257 { |
|
258 aArray.Append(KMTPDeviceDpSupportedOperations[i]); |
|
259 } |
|
260 } |
|
261 break; |
|
262 |
|
263 case EStorageSystemTypes: |
|
264 aArray.Append(CMTPStorageMetaData::ESystemTypeDefaultFileSystem); |
|
265 break; |
|
266 |
|
267 case EObjectProperties: |
|
268 { |
|
269 TInt count(sizeof(KMTPDeviceDpSupportedObjectProperties) / sizeof(KMTPDeviceDpSupportedObjectProperties[0])); |
|
270 for (TInt i(0); (i < count); i++) |
|
271 { |
|
272 aArray.Append(KMTPDeviceDpSupportedObjectProperties[i]); |
|
273 } |
|
274 } |
|
275 break; |
|
276 |
|
277 default: |
|
278 // Unrecognised category, leave aArray unmodified. |
|
279 break; |
|
280 } |
|
281 __FLOG(_L8("Supported - Exit")); |
|
282 } |
|
283 |
|
284 #ifdef __FLOG_ACTIVE |
|
285 void CMTPDeviceDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt aError) |
|
286 #else |
|
287 void CMTPDeviceDataProvider::NotifyEnumerationCompleteL(TUint32 aStorageId, TInt /*aError*/) |
|
288 #endif // __FLOG_ACTIVE |
|
289 { |
|
290 __FLOG(_L8("NotifyEnumerationCompleteL - Entry")); |
|
291 __ASSERT_DEBUG((aStorageId == iPendingEnumerations[KMTPDeviceDpActiveEnumeration]), User::Invariant()); |
|
292 switch(iEnumeratingState) |
|
293 { |
|
294 case EEnumeratingDeviceDataStore: |
|
295 iEnumeratingState = EEnumeratingFolders; |
|
296 iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]); |
|
297 break; |
|
298 |
|
299 case EEnumeratingFolders: |
|
300 __FLOG_VA((_L8("Enumeration of storage 0x%08X completed with error status %d"), aStorageId, aError)); |
|
301 iPendingEnumerations.Remove(KMTPDeviceDpActiveEnumeration); |
|
302 Framework().ObjectEnumerationCompleteL(aStorageId); |
|
303 if (iPendingEnumerations.Count() > 0) |
|
304 { |
|
305 iEnumerator->StartL(iPendingEnumerations[KMTPDeviceDpActiveEnumeration]); |
|
306 } |
|
307 else |
|
308 { |
|
309 iEnumeratingState = EEnumerationComplete; |
|
310 } |
|
311 break; |
|
312 |
|
313 case EEnumerationComplete: |
|
314 default: |
|
315 __DEBUG_ONLY(User::Invariant()); |
|
316 break; |
|
317 } |
|
318 __FLOG(_L8("NotifyEnumerationCompleteL - Exit")); |
|
319 } |
|
320 |
|
321 /** |
|
322 Constructor. |
|
323 */ |
|
324 CMTPDeviceDataProvider::CMTPDeviceDataProvider(TAny* aParams) : |
|
325 CMTPDataProviderPlugin(aParams), |
|
326 iActiveProcessors(KMTPDeviceDpSessionGranularity), |
|
327 iActiveProcessor(-1) |
|
328 { |
|
329 |
|
330 } |
|
331 |
|
332 /** |
|
333 Load devdp extension plugins if present |
|
334 */ |
|
335 void CMTPDeviceDataProvider::LoadExtnPluginsL() |
|
336 { |
|
337 |
|
338 RArray<TUint> extnUidArray; |
|
339 CleanupClosePushL(extnUidArray); |
|
340 iDevDpSingletons.ConfigMgr().GetRssConfigInfoArrayL( extnUidArray, EDevDpExtnUids); |
|
341 |
|
342 TInt count = extnUidArray.Count(); |
|
343 for (TInt i = 0; i < count; i++) |
|
344 { |
|
345 |
|
346 CDevDpExtnPluginMap* extnpluginMap = NULL; |
|
347 extnpluginMap = CDevDpExtnPluginMap::NewL(*this, TUid::Uid(extnUidArray[i])); |
|
348 |
|
349 if(extnpluginMap ) |
|
350 { |
|
351 iExtnPluginMapArray.Append(extnpluginMap); |
|
352 } |
|
353 |
|
354 } |
|
355 CleanupStack::PopAndDestroy(&extnUidArray); |
|
356 } |
|
357 |
|
358 /** |
|
359 Second phase constructor. |
|
360 */ |
|
361 void CMTPDeviceDataProvider::ConstructL() |
|
362 { |
|
363 __FLOG_OPEN(KMTPSubsystem, KComponent); |
|
364 __FLOG(_L8("ConstructL - Entry")); |
|
365 iDevDpSingletons.OpenL(Framework()); |
|
366 iPtrDataStore = &(iDevDpSingletons.DeviceDataStore()); |
|
367 iDpSingletons.OpenL(Framework()); |
|
368 |
|
369 iExclusionMgr = CMTPDevDpExclusionMgr::NewL(Framework()); |
|
370 iDpSingletons.SetExclusionMgrL(*iExclusionMgr); |
|
371 |
|
372 iStorageWatcher = CMTPStorageWatcher::NewL(Framework()); |
|
373 |
|
374 const TUint KProcessLimit = iDevDpSingletons.ConfigMgr().UintValueL(CMTPDeviceDpConfigMgr::EEnumerationIterationLength); |
|
375 |
|
376 TRAPD(err, LoadExtnPluginsL()); |
|
377 // __ASSERT_DEBUG((err == KErrNone), Panic(_L("Invalid resource file "))); |
|
378 if(KErrNone != err) |
|
379 { |
|
380 __FLOG(_L8("\nTere is an issue in loading the plugin !!!!!\n")); |
|
381 } |
|
382 |
|
383 iEnumerator = CMTPFSEnumerator::NewL(Framework(), iDpSingletons.ExclusionMgrL(), *this, KProcessLimit); |
|
384 __FLOG(_L8("ConstructL - Exit")); |
|
385 |
|
386 } |
|
387 |
|
388 void CMTPDeviceDataProvider::OnDevicePropertyChangedL (TMTPDevicePropertyCode& aPropCode) |
|
389 { |
|
390 iEvent.Reset(); |
|
391 iEvent.SetUint16(TMTPTypeEvent::EEventCode, EMTPEventCodeDevicePropChanged ); |
|
392 iEvent.SetUint32(TMTPTypeEvent::EEventSessionID, KMTPSessionAll); |
|
393 iEvent.SetUint32(TMTPTypeEvent::EEventTransactionID, KMTPTransactionIdNone); |
|
394 iEvent.SetUint32(TMTPTypeEvent::EEventParameter1, aPropCode); |
|
395 Framework().SendEventL(iEvent); |
|
396 } |
|
397 |
|
398 /** |
|
399 *This method will return the reference to MMTPDataProviderFramework from CMTPDataProviderPlugin |
|
400 */ |
|
401 MMTPDataProviderFramework& CMTPDeviceDataProvider::DataProviderFramework () |
|
402 { |
|
403 return Framework(); |
|
404 } |
|
405 |
|
406 TInt CMTPDeviceDataProvider::FindExtnPlugin(TUint aOpcode) |
|
407 { |
|
408 TInt noOfEtxnPlugins = iExtnPluginMapArray.Count(); |
|
409 for(TInt i=0; i < noOfEtxnPlugins; i++) |
|
410 { |
|
411 if(iExtnPluginMapArray[i]->SupportedOpCodes()->Find(aOpcode)!= KErrNotFound) |
|
412 { |
|
413 return i; |
|
414 } |
|
415 } |
|
416 return KErrNotFound; |
|
417 } |
|
418 /** |
|
419 Find or create a request processor that can process the request |
|
420 @param aRequest The request to be processed |
|
421 @param aConnection The connection from which the request comes |
|
422 @return the index of the found/created request processor |
|
423 */ |
|
424 TInt CMTPDeviceDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
425 { |
|
426 __FLOG(_L8("LocateRequestProcessorL - Entry")); |
|
427 TInt index = KErrNotFound; |
|
428 TInt count = iActiveProcessors.Count(); |
|
429 for(TInt i = 0; i < count; i++) |
|
430 { |
|
431 if(iActiveProcessors[i]->Match(aRequest, aConnection)) |
|
432 { |
|
433 index = i; |
|
434 break; |
|
435 } |
|
436 } |
|
437 if(index == KErrNotFound) |
|
438 { |
|
439 MMTPRequestProcessor* processor = MTPDeviceDpProcessor::CreateL(Framework(), aRequest, aConnection); |
|
440 __ASSERT_DEBUG(processor, Panic(EMTPDevDpNoMatchingProcessor)); |
|
441 CleanupReleasePushL(*processor); |
|
442 iActiveProcessors.AppendL(processor); |
|
443 TUint16 operationCode(aRequest.Uint16(TMTPTypeRequest::ERequestOperationCode)); |
|
444 |
|
445 if (operationCode >= EMTPOpCodeGetDevicePropDesc && operationCode <=EMTPOpCodeResetDevicePropValue) |
|
446 { |
|
447 TUint propCode = aRequest.Uint32(TMTPTypeRequest::ERequestParameter1); |
|
448 TInt foundplugin = FindExtnPlugin (propCode); |
|
449 if(foundplugin!= KErrNotFound) |
|
450 { |
|
451 iDevDpSingletons.DeviceDataStore().SetExtnDevicePropDp(iExtnPluginMapArray[foundplugin]->ExtPlugin()); |
|
452 } |
|
453 } |
|
454 CleanupStack::Pop(); |
|
455 index = count; |
|
456 } |
|
457 __FLOG(_L8("LocateRequestProcessorL - Exit")); |
|
458 return index; |
|
459 } |
|
460 |
|
461 /** |
|
462 Finds a request processor that can process the event |
|
463 @param aEvent The event to be processed |
|
464 @param aConnection The connection from which the request comes |
|
465 @return the index of the found request processor, KErrNotFound if not found |
|
466 */ |
|
467 TInt CMTPDeviceDataProvider::LocateRequestProcessorL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection) |
|
468 { |
|
469 __FLOG(_L8("LocateRequestProcessorL - Entry")); |
|
470 TInt index = KErrNotFound; |
|
471 TInt count = iActiveProcessors.Count(); |
|
472 for(TInt i = 0; i < count; i++) |
|
473 { |
|
474 if(iActiveProcessors[i]->Match(aEvent, aConnection)) |
|
475 { |
|
476 index = i; |
|
477 break; |
|
478 } |
|
479 } |
|
480 __FLOG(_L8("LocateRequestProcessorL - Exit")); |
|
481 return index; |
|
482 } |
|
483 |
|
484 /** |
|
485 Cleans up outstanding request processors when a session is closed. |
|
486 @param aSession notification parameter block |
|
487 */ |
|
488 void CMTPDeviceDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession) |
|
489 { |
|
490 __FLOG(_L8("SessionClosedL - Entry")); |
|
491 TInt count = iActiveProcessors.Count(); |
|
492 while(count--) |
|
493 { |
|
494 MMTPRequestProcessor* processor = iActiveProcessors[count]; |
|
495 TUint32 sessionId = processor->SessionId(); |
|
496 if((sessionId == aSession.iMTPId) && (processor->Connection().ConnectionId() == aSession.iConnection.ConnectionId())) |
|
497 { |
|
498 iActiveProcessors.Remove(count); |
|
499 if (count == iActiveProcessor) |
|
500 { |
|
501 iActiveProcessorRemoved = ETrue; |
|
502 } |
|
503 else |
|
504 { |
|
505 processor->Release(); |
|
506 } |
|
507 } |
|
508 } |
|
509 __FLOG(_L8("SessionClosedL - Exit")); |
|
510 } |
|
511 |
|
512 /** |
|
513 Prepares for a newly-opened session. |
|
514 @param aSession notification parameter block |
|
515 */ |
|
516 #ifdef __FLOG_ACTIVE |
|
517 void CMTPDeviceDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& aSession) |
|
518 #else |
|
519 void CMTPDeviceDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/) |
|
520 #endif |
|
521 { |
|
522 __FLOG(_L8("SessionOpenedL - Entry")); |
|
523 __FLOG_VA((_L8("SessionID = %d"), aSession.iMTPId)); |
|
524 __FLOG(_L8("SessionOpenedL - Exit")); |
|
525 } |
|
526 |