|
1 // Copyright (c) 2010 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 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include <mtp/mmtpconnection.h> |
|
22 #include <mtp/mmtpdataproviderframework.h> |
|
23 #include <mtp/mtpdataproviderapitypes.h> |
|
24 |
|
25 #include "cmtpplaybackcontroldp.h" |
|
26 #include "cmtprequestprocessor.h" |
|
27 #include "mtpplaybackcontroldpprocessor.h" |
|
28 #include "cmtpplaybackmap.h" |
|
29 #include "cmtpplaybackproperty.h" |
|
30 #include "mmtpplaybackinterface.h" |
|
31 #include "cmtpplaybackevent.h" |
|
32 #include "mtpplaybackcontrolpanic.h" |
|
33 |
|
34 |
|
35 // Class constants. |
|
36 __FLOG_STMT(_LIT8(KComponent,"PlaybackControlDataProvider");) |
|
37 static const TInt KMTPPlaybackControlDpSessionGranularity(3); |
|
38 |
|
39 /** |
|
40 MTP playback control data provider plug-in factory method. |
|
41 @return A pointer to an MTP playback control data provider plug-in. Ownership IS |
|
42 transfered. |
|
43 @leave One of the system wide error codes, if a processing failure occurs. |
|
44 */ |
|
45 TAny* CMTPPlaybackControlDataProvider::NewL(TAny* aParams) |
|
46 { |
|
47 CMTPPlaybackControlDataProvider* self = new (ELeave) CMTPPlaybackControlDataProvider(aParams); |
|
48 CleanupStack::PushL(self); |
|
49 self->ConstructL(); |
|
50 CleanupStack::Pop(self); |
|
51 return self; |
|
52 } |
|
53 |
|
54 /** |
|
55 Destructor |
|
56 */ |
|
57 CMTPPlaybackControlDataProvider::~CMTPPlaybackControlDataProvider() |
|
58 { |
|
59 __FLOG(_L8("~CMTPPlaybackControlDataProvider - Entry")); |
|
60 TInt count = iActiveProcessors.Count(); |
|
61 while(count--) |
|
62 { |
|
63 iActiveProcessors[count]->Release(); |
|
64 } |
|
65 iActiveProcessors.Close(); |
|
66 delete iPlaybackMap; |
|
67 delete iPlaybackProperty; |
|
68 if(iPlaybackControl) |
|
69 { |
|
70 iPlaybackControl->Close(); |
|
71 } |
|
72 __FLOG(_L8("~CMTPPlaybackControlDataProvider - Exit")); |
|
73 __FLOG_CLOSE; |
|
74 } |
|
75 |
|
76 void CMTPPlaybackControlDataProvider::Cancel() |
|
77 { |
|
78 |
|
79 } |
|
80 |
|
81 void CMTPPlaybackControlDataProvider::ProcessEventL(const TMTPTypeEvent& /*aEvent*/, MMTPConnection& /*aConnection*/) |
|
82 { |
|
83 __FLOG(_L8("ProcessEventL - Entry")); |
|
84 __FLOG(_L8("ProcessEventL - Exit")); |
|
85 } |
|
86 |
|
87 void CMTPPlaybackControlDataProvider::ProcessNotificationL(TMTPNotification aNotification, const TAny* aParams) |
|
88 { |
|
89 __FLOG(_L8("ProcessNotificationL - Entry")); |
|
90 switch (aNotification) |
|
91 { |
|
92 case EMTPSessionClosed: |
|
93 SessionClosedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
94 break; |
|
95 |
|
96 case EMTPSessionOpened: |
|
97 SessionOpenedL(*reinterpret_cast<const TMTPNotificationParamsSessionChange*>(aParams)); |
|
98 break; |
|
99 default: |
|
100 // Ignore all other notifications. |
|
101 break; |
|
102 } |
|
103 __FLOG(_L8("ProcessNotificationL - Exit")); |
|
104 } |
|
105 |
|
106 void CMTPPlaybackControlDataProvider::ProcessRequestPhaseL(TMTPTransactionPhase aPhase, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
107 { |
|
108 __FLOG(_L8("ProcessRequestPhaseL - Entry")); |
|
109 TInt index = LocateRequestProcessorL(aRequest, aConnection); |
|
110 __ASSERT_DEBUG(index != KErrNotFound, Panic(EMTPPBArgumentErr)); |
|
111 MMTPRequestProcessor* processor = iActiveProcessors[index]; |
|
112 iActiveProcessor = index; |
|
113 iActiveProcessorRemoved = EFalse; |
|
114 TBool result = processor->HandleRequestL(aRequest, aPhase); |
|
115 if (iActiveProcessorRemoved) |
|
116 { |
|
117 processor->Release(); // destroy the processor |
|
118 } |
|
119 else if (result) |
|
120 { |
|
121 processor->Release(); |
|
122 iActiveProcessors.Remove(index); |
|
123 } |
|
124 iActiveProcessor = -1; |
|
125 __FLOG(_L8("ProcessRequestPhaseL - Exit")); |
|
126 } |
|
127 |
|
128 void CMTPPlaybackControlDataProvider::Supported(TMTPSupportCategory aCategory, RArray<TUint>& aArray) const |
|
129 { |
|
130 __FLOG(_L8("Supported - Entry")); |
|
131 |
|
132 switch (aCategory) |
|
133 { |
|
134 case EDeviceProperties: |
|
135 { |
|
136 TInt count = sizeof(KMTPPlaybackControlDpSupportedProperties) / sizeof(KMTPPlaybackControlDpSupportedProperties[0]); |
|
137 for(TInt i = 0; i < count; i++) |
|
138 { |
|
139 aArray.Append(KMTPPlaybackControlDpSupportedProperties[i]); |
|
140 } |
|
141 } |
|
142 break; |
|
143 |
|
144 case EOperations: |
|
145 { |
|
146 TInt count = sizeof(KMTPPlaybackControlDpSupportedOperations) / sizeof(KMTPPlaybackControlDpSupportedOperations[0]); |
|
147 for(TInt i = 0; i < count; i++) |
|
148 { |
|
149 aArray.Append(KMTPPlaybackControlDpSupportedOperations[i]); |
|
150 } |
|
151 } |
|
152 break; |
|
153 |
|
154 case EEvents: |
|
155 { |
|
156 TInt count = sizeof(KMTPPlaybackControlDpSupportedEvents) / sizeof(KMTPPlaybackControlDpSupportedEvents[0]); |
|
157 for(TInt i = 0; i < count; i++) |
|
158 { |
|
159 aArray.Append(KMTPPlaybackControlDpSupportedEvents[i]); |
|
160 } |
|
161 } |
|
162 break; |
|
163 |
|
164 default: |
|
165 // Unrecognised category, leave aArray unmodified. |
|
166 break; |
|
167 } |
|
168 __FLOG(_L8("Supported - Exit")); |
|
169 } |
|
170 |
|
171 /** |
|
172 Constructor. |
|
173 */ |
|
174 CMTPPlaybackControlDataProvider::CMTPPlaybackControlDataProvider(TAny* aParams) : |
|
175 CMTPDataProviderPlugin(aParams), |
|
176 iActiveProcessors(KMTPPlaybackControlDpSessionGranularity), |
|
177 iActiveProcessor(-1), |
|
178 iRequestToResetPbCtrl(EFalse) |
|
179 { |
|
180 |
|
181 } |
|
182 |
|
183 /** |
|
184 Second phase constructor. |
|
185 */ |
|
186 void CMTPPlaybackControlDataProvider::ConstructL() |
|
187 { |
|
188 __FLOG_OPEN(KMTPSubsystem, KComponent); |
|
189 __FLOG(_L8("ConstructL - Entry")); |
|
190 iPlaybackProperty = CMTPPlaybackProperty::NewL(); |
|
191 iPlaybackMap = CMTPPlaybackMap::NewL(Framework(),*iPlaybackProperty); |
|
192 __FLOG(_L8("ConstructL - Exit")); |
|
193 } |
|
194 |
|
195 void CMTPPlaybackControlDataProvider::SendEventL(TMTPDevicePropertyCode aPropCode) |
|
196 { |
|
197 __FLOG(_L8("SendEventL - Entry")); |
|
198 iEvent.Reset(); |
|
199 iEvent.SetUint16(TMTPTypeEvent::EEventCode, EMTPEventCodeDevicePropChanged ); |
|
200 iEvent.SetUint32(TMTPTypeEvent::EEventSessionID, KMTPSessionAll); |
|
201 iEvent.SetUint32(TMTPTypeEvent::EEventTransactionID, KMTPTransactionIdNone); |
|
202 iEvent.SetUint32(TMTPTypeEvent::EEventParameter1, aPropCode); |
|
203 Framework().SendEventL(iEvent); |
|
204 __FLOG(_L8("SendEventL - Exit")); |
|
205 } |
|
206 |
|
207 /** |
|
208 Find or create a request processor that can process the request |
|
209 @param aRequest The request to be processed |
|
210 @param aConnection The connection from which the request comes |
|
211 @return the index of the found/created request processor |
|
212 */ |
|
213 TInt CMTPPlaybackControlDataProvider::LocateRequestProcessorL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection) |
|
214 { |
|
215 __FLOG(_L8("LocateRequestProcessorL - Entry")); |
|
216 TInt index = KErrNotFound; |
|
217 TInt count = iActiveProcessors.Count(); |
|
218 for(TInt i = 0; i < count; i++) |
|
219 { |
|
220 if(iActiveProcessors[i]->Match(aRequest, aConnection)) |
|
221 { |
|
222 index = i; |
|
223 break; |
|
224 } |
|
225 } |
|
226 if(index == KErrNotFound) |
|
227 { |
|
228 MMTPRequestProcessor* processor = MTPPlaybackControlDpProcessor::CreateL(Framework(), aRequest, aConnection, *this); |
|
229 __ASSERT_DEBUG(processor, Panic(EMTPPBArgumentErr)); |
|
230 CleanupReleasePushL(*processor); |
|
231 iActiveProcessors.AppendL(processor); |
|
232 CleanupStack::Pop(); |
|
233 index = count; |
|
234 } |
|
235 |
|
236 __FLOG(_L8("LocateRequestProcessorL - Exit")); |
|
237 return index; |
|
238 } |
|
239 |
|
240 /** |
|
241 Cleans up outstanding request processors when a session is closed. |
|
242 @param aSession notification parameter block |
|
243 */ |
|
244 void CMTPPlaybackControlDataProvider::SessionClosedL(const TMTPNotificationParamsSessionChange& aSession) |
|
245 { |
|
246 __FLOG(_L8("SessionClosedL - Entry")); |
|
247 TInt count = iActiveProcessors.Count(); |
|
248 while (count--) |
|
249 { |
|
250 MMTPRequestProcessor* processor = iActiveProcessors[count]; |
|
251 TUint32 sessionId(processor->SessionId()); |
|
252 if ((sessionId == aSession.iMTPId) && (processor->Connection().ConnectionId() == aSession.iConnection.ConnectionId())) |
|
253 { |
|
254 iActiveProcessors.Remove(count); |
|
255 if (count == iActiveProcessor) |
|
256 { |
|
257 iActiveProcessorRemoved = ETrue; |
|
258 } |
|
259 else |
|
260 { |
|
261 processor->Release(); |
|
262 } |
|
263 } |
|
264 } |
|
265 |
|
266 if(iPlaybackControl) |
|
267 { |
|
268 iPlaybackControl->Close(); |
|
269 iPlaybackControl = NULL; |
|
270 } |
|
271 |
|
272 __FLOG(_L8("SessionClosedL - Exit")); |
|
273 } |
|
274 |
|
275 /** |
|
276 Prepares for a newly-opened session. |
|
277 @param aSession notification parameter block |
|
278 */ |
|
279 #ifdef __FLOG_ACTIVE |
|
280 void CMTPPlaybackControlDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& aSession) |
|
281 #else |
|
282 void CMTPPlaybackControlDataProvider::SessionOpenedL(const TMTPNotificationParamsSessionChange& /*aSession*/) |
|
283 #endif |
|
284 { |
|
285 __FLOG(_L8("SessionOpenedL - Entry")); |
|
286 __FLOG_VA((_L8("SessionID = %d"), aSession.iMTPId)); |
|
287 __FLOG(_L8("SessionOpenedL - Exit")); |
|
288 } |
|
289 |
|
290 void CMTPPlaybackControlDataProvider::StartObjectEnumerationL(TUint32 aStorageId, TBool /*aPersistentFullEnumeration*/) |
|
291 { |
|
292 __FLOG(_L8("StartObjectEnumerationL - Entry")); |
|
293 //This DP doesn't manage data. |
|
294 Framework().ObjectEnumerationCompleteL(aStorageId); |
|
295 __FLOG(_L8("StartObjectEnumerationL - Exit")); |
|
296 } |
|
297 |
|
298 void CMTPPlaybackControlDataProvider::StartStorageEnumerationL() |
|
299 { |
|
300 __FLOG(_L8("StartStorageEnumerationL - Entry")); |
|
301 //This DP doesn't manage data. |
|
302 Framework().StorageEnumerationCompleteL(); |
|
303 __FLOG(_L8("StartStorageEnumerationL - Exit")); |
|
304 } |
|
305 |
|
306 void CMTPPlaybackControlDataProvider::HandlePlaybackEventL(CMTPPlaybackEvent* aEvent, TInt aErr) |
|
307 { |
|
308 __FLOG(_L8("HandlePlaybackEventL - Entry")); |
|
309 |
|
310 if(aErr != KPlaybackErrNone) |
|
311 { |
|
312 if(aErr == KPlaybackErrDeviceUnavailable ) |
|
313 { |
|
314 iRequestToResetPbCtrl = ETrue; |
|
315 //Report error to initiator, . |
|
316 SendEventL(EMTPDevicePropCodePlaybackObject); |
|
317 SendEventL(EMTPDevicePropCodePlaybackRate); |
|
318 SendEventL(EMTPDevicePropCodePlaybackContainerIndex); |
|
319 SendEventL(EMTPDevicePropCodePlaybackPosition); |
|
320 } |
|
321 return; |
|
322 } |
|
323 |
|
324 __ASSERT_DEBUG((aEvent != NULL), Panic(EMTPPBDataNullErr)); |
|
325 __ASSERT_ALWAYS((aEvent != NULL), User::Leave(KErrArgument)); |
|
326 __FLOG_1(_L8("aEvent %d"), aEvent->PlaybackEvent()); |
|
327 |
|
328 switch(aEvent->PlaybackEvent()) |
|
329 { |
|
330 case EPlaybackEventVolumeUpdate: |
|
331 { |
|
332 SendEventL(EMTPDevicePropCodeVolume); |
|
333 } |
|
334 break; |
|
335 case EPlaybackEventStateUpdate: |
|
336 { |
|
337 SendEventL(EMTPDevicePropCodePlaybackRate); |
|
338 } |
|
339 break; |
|
340 case EPlaybackEventObjectUpdate: |
|
341 { |
|
342 SendEventL(EMTPDevicePropCodePlaybackObject); |
|
343 } |
|
344 break; |
|
345 case EPlaybackEventObjectIndexUpdate: |
|
346 { |
|
347 SendEventL(EMTPDevicePropCodePlaybackContainerIndex); |
|
348 } |
|
349 break; |
|
350 |
|
351 default: |
|
352 User::Leave(KErrArgument); |
|
353 break; |
|
354 } |
|
355 |
|
356 __FLOG(_L8("HandlePlaybackEventL - Exit")); |
|
357 } |
|
358 |
|
359 CMTPPlaybackMap& CMTPPlaybackControlDataProvider::GetPlaybackMap() const |
|
360 { |
|
361 __ASSERT_DEBUG((iPlaybackMap != NULL), Panic(EMTPPBDataNullErr)); |
|
362 return *iPlaybackMap; |
|
363 } |
|
364 |
|
365 CMTPPlaybackProperty& CMTPPlaybackControlDataProvider::GetPlaybackProperty() const |
|
366 { |
|
367 __ASSERT_DEBUG((iPlaybackProperty != NULL), Panic(EMTPPBDataNullErr)); |
|
368 return *iPlaybackProperty; |
|
369 } |
|
370 |
|
371 MMTPPlaybackControl& CMTPPlaybackControlDataProvider::GetPlaybackControlL() |
|
372 { |
|
373 __FLOG(_L8("GetPlaybackControlL - Entry")); |
|
374 if(iPlaybackControl == NULL) |
|
375 { |
|
376 iPlaybackControl = MMTPPlaybackControl::NewL(*this); |
|
377 } |
|
378 else if(iRequestToResetPbCtrl) |
|
379 { |
|
380 iRequestToResetPbCtrl = EFalse; |
|
381 iPlaybackControl->Close(); |
|
382 iPlaybackControl = NULL; |
|
383 iPlaybackControl = MMTPPlaybackControl::NewL(*this); |
|
384 } |
|
385 __FLOG(_L8("GetPlaybackControlL - Exit")); |
|
386 return *iPlaybackControl; |
|
387 } |
|
388 |
|
389 void CMTPPlaybackControlDataProvider::RequestToResetPbCtrl() |
|
390 { |
|
391 iRequestToResetPbCtrl = ETrue; |
|
392 } |