1 /* |
|
2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "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 * |
|
14 * Description: Plays remote images and videos locally on the device |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 // System |
|
21 #include <AiwGenericParam.h> |
|
22 #include <AiwGenericParam.hrh> |
|
23 #include <AiwCommon.hrh> |
|
24 |
|
25 #include <aknnotewrappers.h> |
|
26 #include <DocumentHandler.h> |
|
27 #include <apmstd.h> |
|
28 #include <AknWaitDialog.h> |
|
29 #include <aknnotewrappers.h> |
|
30 #include <upnpdlnaprotocolinfo.h> |
|
31 #include <upnpcommonui.rsg> |
|
32 #include <utf.h> |
|
33 #include <bautils.h> |
|
34 |
|
35 // upnp specific MACRO definition |
|
36 #include "upnpconstantdefs.h" |
|
37 // upnp stack api |
|
38 #include <upnpitem.h> |
|
39 #include <upnpobject.h> |
|
40 #include <upnpstring.h> |
|
41 |
|
42 // upnp framework / avcontroller api |
|
43 #include "upnpavcontroller.h" // MUPnPAVController |
|
44 #include "upnpfiledownloadsession.h" // MUPnPFileDownloadSession |
|
45 #include "upnpavbrowsingsession.h" |
|
46 |
|
47 // upnp framework / avcontroller helper api |
|
48 #include "upnpdlnautility.h" |
|
49 #include "upnpitemutility.h" |
|
50 #include "upnpfileutility.h" |
|
51 |
|
52 // upnp framework / internal api's |
|
53 #include "upnpcommonutils.h" |
|
54 #include "upnpsettingsengine.h" // get selected download location |
|
55 |
|
56 // USER INCLUDE FILES |
|
57 #include "upnpcommonui.h" |
|
58 #include "upnplocalplayer.h" |
|
59 #include "upnpdeviceobserver.h" |
|
60 |
|
61 // DEBUG |
|
62 _LIT( KComponentLogfile, "commonui.txt"); |
|
63 #include "upnplog.h" |
|
64 |
|
65 // CONSTANT DEFINITIONS |
|
66 _LIT8( KProtocolInfo, "protocolInfo" ); |
|
67 _LIT8( KHttpDes, "http://" ); |
|
68 _LIT8( KHttpGetDes, "http-get" ); |
|
69 _LIT8( KHttpEqual, "=" ); |
|
70 |
|
71 const TInt KDownloadPosition = 0; |
|
72 |
|
73 // Video mimetypes that can be played on device |
|
74 |
|
75 |
|
76 // ============================ MEMBER FUNCTIONS ============================ |
|
77 |
|
78 // -------------------------------------------------------------------------- |
|
79 // CUPnPLocalPlayer::CUPnPLocalPlayer |
|
80 // C++ default constructor can NOT contain any code, that |
|
81 // might leave. |
|
82 // -------------------------------------------------------------------------- |
|
83 // |
|
84 CUPnPLocalPlayer::CUPnPLocalPlayer( MUPnPAVController& aAVController, |
|
85 MUPnPAVBrowsingSession& aBrowseSession, |
|
86 CUPnPCommonUI& aCommonUI ): |
|
87 iCommonUI(aCommonUI) |
|
88 { |
|
89 __LOG( "CUPnPLocalPlayer::CUPnPLocalPlayer" ); |
|
90 iAVController = &aAVController; |
|
91 iExitReason = KErrNone; |
|
92 iBrowseSession = &aBrowseSession; |
|
93 __LOG( "CUPnPLocalPlayer::CUPnPLocalPlayer-END" ); |
|
94 } |
|
95 |
|
96 |
|
97 |
|
98 // -------------------------------------------------------------------------- |
|
99 // CUPnPLocalPlayer::ConstructL |
|
100 // Symbian 2nd phase constructor can leave. |
|
101 // -------------------------------------------------------------------------- |
|
102 // |
|
103 void CUPnPLocalPlayer::ConstructL() |
|
104 { |
|
105 __LOG( "CUPnPLocalPlayer::ConstructL" ); |
|
106 iDocumentHandler = CDocumentHandler::NewL(); |
|
107 iDocumentHandler->SetExitObserver( this ); |
|
108 User::LeaveIfError( iFs.Connect() ); |
|
109 iDownloadSession = &iAVController->StartDownloadSessionL( |
|
110 iBrowseSession->Device() ); |
|
111 __LOG( "CUPnPLocalPlayer::ConstructL-END" ); |
|
112 } |
|
113 |
|
114 // -------------------------------------------------------------------------- |
|
115 // CUPnPLocalPlayer::NewL |
|
116 // Two-phased constructor. |
|
117 // -------------------------------------------------------------------------- |
|
118 // |
|
119 EXPORT_C CUPnPLocalPlayer* CUPnPLocalPlayer::NewL( |
|
120 MUPnPAVController& aAVController, |
|
121 MUPnPAVBrowsingSession& aBrowseSession, |
|
122 CUPnPCommonUI& aCommonUI ) |
|
123 { |
|
124 CUPnPLocalPlayer* self = new( ELeave )CUPnPLocalPlayer( aAVController, |
|
125 aBrowseSession, |
|
126 aCommonUI ); |
|
127 CleanupStack::PushL(self); |
|
128 self->ConstructL(); |
|
129 CleanupStack::Pop( self ); |
|
130 __LOG( "CUPnPLocalPlayer::NewL-END" ); |
|
131 return self; |
|
132 } |
|
133 |
|
134 // -------------------------------------------------------------------------- |
|
135 // CUPnPLocalPlayer::~CUPnPLocalPlayer |
|
136 // Destructor. |
|
137 // -------------------------------------------------------------------------- |
|
138 // |
|
139 CUPnPLocalPlayer::~CUPnPLocalPlayer() |
|
140 { |
|
141 __LOG( "CUPnPLocalPlayer::~CUPnPLocalPlayer" ); |
|
142 |
|
143 // If download session is running, stop it |
|
144 if( iAVController && |
|
145 iDownloadSession ) |
|
146 { |
|
147 iAVController->StopDownloadSession( *iDownloadSession ); |
|
148 } |
|
149 |
|
150 delete iDocumentHandler; |
|
151 |
|
152 delete iWaitNoteDialog; |
|
153 |
|
154 delete iItem; |
|
155 |
|
156 if( iFilePath ) |
|
157 { |
|
158 iFs.Delete( *iFilePath ); |
|
159 delete iFilePath; |
|
160 } |
|
161 iFs.Close(); |
|
162 |
|
163 __LOG( "CUPnPLocalPlayer::~CUPnPLocalPlayer-END" ); |
|
164 } |
|
165 |
|
166 // -------------------------------------------------------------------------- |
|
167 // CUPnPLocalPlayer::PlayL |
|
168 // Play a selected item. |
|
169 // -------------------------------------------------------------------------- |
|
170 // |
|
171 EXPORT_C void CUPnPLocalPlayer::PlayL( const CUpnpObject& aItem ) |
|
172 { |
|
173 __LOG( "CUPnPLocalPlayer::PlayL" ); |
|
174 |
|
175 // recreate iItem |
|
176 delete iItem; iItem = NULL; |
|
177 iItem = CUpnpItem::NewL(); |
|
178 iItem->CopyL( aItem ); |
|
179 |
|
180 if ( !IsLocallySupportedL( *iItem ) ) |
|
181 { |
|
182 User::Leave( KErrNotSupported ); |
|
183 } |
|
184 |
|
185 //in order not to get two callbacks when MS is lost, |
|
186 // in CUPnPLocalPlayer and CUPnPBrowseDialog |
|
187 iBrowseSessionObserver = iBrowseSession->Observer(); |
|
188 iBrowseSession->RemoveObserver(); |
|
189 iFs.Close(); |
|
190 |
|
191 User::LeaveIfError( iFs.Connect() ); |
|
192 User::LeaveIfError( iFs.ShareProtected() ); |
|
193 delete iFilePath; iFilePath = NULL; |
|
194 iExitReason = KErrNone; |
|
195 iDownloadSession->SetObserver( *this ); |
|
196 |
|
197 /** |
|
198 * All the temporiarily downloaded files should go to the |
|
199 * hidden folder \data\download\media\temp |
|
200 * fix for ETLU-7LKCJB |
|
201 */ |
|
202 //create a file path which should contain the absolute file path |
|
203 //e.g c:\data\download\media\temp\image.jpg |
|
204 |
|
205 iFilePath = HBufC::NewL( KMaxFileName ); |
|
206 HBufC* copyLocation = HBufC::NewLC( KMaxFileName ); |
|
207 CUPnPSettingsEngine* settingsEngine = CUPnPSettingsEngine::NewL(); |
|
208 CleanupStack::PushL( settingsEngine ); |
|
209 TBool copyLocationIsPhoneMemory = 0; // not used in this case |
|
210 TPtr copyLocationPtr( copyLocation->Des() ); |
|
211 settingsEngine->GetCopyLocationL( copyLocationPtr, |
|
212 copyLocationIsPhoneMemory ); |
|
213 |
|
214 CleanupStack::PopAndDestroy( settingsEngine ); |
|
215 |
|
216 iFilePath->Des().Append( *copyLocation ); |
|
217 CleanupStack::PopAndDestroy( copyLocation ); |
|
218 |
|
219 _LIT( KTempFolder, "temp\\"); |
|
220 iFilePath->Des().Append( KTempFolder() ); |
|
221 |
|
222 //check the existence of the target folder |
|
223 if( !BaflUtils::FolderExists( iFs, *iFilePath ) ) |
|
224 { |
|
225 User::LeaveIfError( iFs.MkDirAll( *iFilePath ) ); |
|
226 } |
|
227 |
|
228 User::LeaveIfError( iFs.SetAtt( *iFilePath, |
|
229 KEntryAttHidden, |
|
230 KEntryAttNormal ) ); |
|
231 |
|
232 //Get the title of the given item |
|
233 HBufC* title16 = UpnpString::ToUnicodeL( aItem.Title() ); |
|
234 CleanupStack::PushL( title16 ); |
|
235 HBufC* title16checked = |
|
236 UPnPCommonUtils::ReplaceIllegalFilenameCharactersL( *title16 ); |
|
237 CleanupStack::PopAndDestroy( title16 ); |
|
238 |
|
239 iFilePath->Des().Append( *title16checked ); |
|
240 delete title16checked; title16checked = NULL; |
|
241 //Get the extension of the given item |
|
242 |
|
243 const CUpnpItem* item = (CUpnpItem*)(&aItem); |
|
244 const CUpnpElement* tmpEl = &( UPnPItemUtility::ResourceFromItemL( |
|
245 *item ) ); |
|
246 |
|
247 if( !UPnPFileUtility::FitsInMemory( *tmpEl) ) |
|
248 { |
|
249 User::Leave( KErrDiskFull ); |
|
250 } |
|
251 |
|
252 const CUpnpAttribute* tmpAttInfo = UPnPItemUtility::FindAttributeByName( |
|
253 *tmpEl, KAttributeProtocolInfo ); |
|
254 |
|
255 User::LeaveIfNull( const_cast<CUpnpAttribute*>(tmpAttInfo ) ); |
|
256 |
|
257 CUpnpDlnaProtocolInfo* tmpProtocolInfo = CUpnpDlnaProtocolInfo::NewL( |
|
258 tmpAttInfo->Value() ); |
|
259 |
|
260 CleanupStack::PushL( tmpProtocolInfo ); |
|
261 |
|
262 HBufC* fileExt = NULL; |
|
263 |
|
264 fileExt = UPnPCommonUtils::FileExtensionByMimeTypeL( |
|
265 tmpProtocolInfo->ThirdField() ); |
|
266 |
|
267 User::LeaveIfNull( fileExt ); |
|
268 |
|
269 iFilePath->Des().Append( *fileExt ); |
|
270 |
|
271 delete fileExt; fileExt = NULL; |
|
272 |
|
273 CleanupStack::PopAndDestroy( tmpProtocolInfo ); |
|
274 |
|
275 TInt err = KErrNone; |
|
276 |
|
277 RFile rfile; |
|
278 err = rfile.Create(iFs, *iFilePath, EFileWrite ); |
|
279 |
|
280 CleanupClosePushL( rfile ); |
|
281 if( KErrAlreadyExists == err ) |
|
282 { |
|
283 __LOG( "Already exists -> Delete old and create new" ); |
|
284 User::LeaveIfError( iFs.Delete( *iFilePath ) ); |
|
285 User::LeaveIfError( rfile.Create(iFs, *iFilePath, EFileWrite ) ); |
|
286 } |
|
287 |
|
288 iDownloadSession->StartDownloadL( *tmpEl, |
|
289 ( CUpnpItem& )aItem, |
|
290 rfile, |
|
291 KDownloadPosition ); |
|
292 CleanupStack::PopAndDestroy(&rfile); |
|
293 |
|
294 iWaitingNote = EFalse; |
|
295 if( !iWaitingNote ) //if ReserveLocalMSServicesCompleted is not called |
|
296 { //immediately |
|
297 iWaitingNote = ETrue; |
|
298 StartWaitingNoteL(); |
|
299 } |
|
300 |
|
301 __LOG1( "CUPnPLocalPlayer::PlayL-END %d", iExitReason ); |
|
302 if( iExitReason != KErrNone ) |
|
303 { |
|
304 User::Leave( iExitReason ); |
|
305 } |
|
306 } |
|
307 |
|
308 // -------------------------------------------------------------------------- |
|
309 // CUPnPLocalPlayer::TransferStarted. |
|
310 // -------------------------------------------------------------------------- |
|
311 // |
|
312 void CUPnPLocalPlayer::TransferStarted( TInt aKey, TInt aStatus ) |
|
313 { |
|
314 __LOG( "CUPnPLocalPlayer::TransferStarted" ); |
|
315 if( aStatus != KErrNone) |
|
316 { |
|
317 iExitReason = aStatus; |
|
318 } |
|
319 else if( aKey != KDownloadPosition ) |
|
320 { |
|
321 iExitReason = KErrGeneral; |
|
322 } |
|
323 |
|
324 if( iExitReason != KErrNone ) |
|
325 { |
|
326 FinishNote(); |
|
327 } |
|
328 __LOG( "CUPnPLocalPlayer::TransferStarted-END" ); |
|
329 } |
|
330 |
|
331 // -------------------------------------------------------------------------- |
|
332 // CUPnPLocalPlayer::TransferCompleted. |
|
333 // -------------------------------------------------------------------------- |
|
334 // |
|
335 void CUPnPLocalPlayer::TransferCompleted( TInt aKey, |
|
336 TInt aStatus, |
|
337 const TDesC& aFilePath ) |
|
338 { |
|
339 __LOG( "CUPnPLocalPlayer::TransferCompleted" ); |
|
340 |
|
341 if( aKey != KDownloadPosition ) |
|
342 { |
|
343 iExitReason = KErrGeneral; |
|
344 FinishNote(); |
|
345 } |
|
346 else |
|
347 { |
|
348 TRAP_IGNORE( CopyCompleteL( aStatus, aFilePath ) ); |
|
349 } |
|
350 |
|
351 __LOG( "CUPnPLocalPlayer::TransferCompleted-END" ); |
|
352 } |
|
353 |
|
354 // -------------------------------------------------------------------------- |
|
355 // CUPnPLocalPlayer::CopyCompleteL |
|
356 // Returns from UPnP AV control point when a copy operation has been finished |
|
357 // -------------------------------------------------------------------------- |
|
358 void CUPnPLocalPlayer::CopyCompleteL( TInt aError, |
|
359 const TDesC& /*aFilePath*/ ) |
|
360 { |
|
361 __LOG1( "CopyCompleteL %d", aError ); |
|
362 |
|
363 FinishNote(); |
|
364 // If copying was successful, play the copied item |
|
365 if( KErrNone == aError ) |
|
366 { |
|
367 // iFilePath Contains UTF8 content,we need change |
|
368 // to TDesC8 first ,Using Copy don't lost any data,because the |
|
369 //low byte is NULL |
|
370 TBuf8<KMaxFileName> filename; |
|
371 filename.Copy( *iFilePath ); |
|
372 |
|
373 HBufC* temp = iFilePath; |
|
374 iFilePath = NULL; |
|
375 |
|
376 // try transform UTF8 to UniCode |
|
377 HBufC* unicodename = CnvUtfConverter::ConvertToUnicodeFromUtf8L( |
|
378 filename ); |
|
379 CleanupStack::PushL( unicodename ); |
|
380 |
|
381 // Rename the file |
|
382 iFilePath = UPnPCommonUtils::RenameFileL( *unicodename ) ; |
|
383 if( iFilePath ) |
|
384 { |
|
385 delete temp; temp = NULL; |
|
386 } |
|
387 else |
|
388 { |
|
389 iFilePath = temp; |
|
390 } |
|
391 CleanupStack::PopAndDestroy( unicodename ); |
|
392 unicodename = NULL; |
|
393 |
|
394 if( iFilePath ) |
|
395 { |
|
396 |
|
397 // fix for TSW: ESLX-7L3DMX |
|
398 // OpenFileEmbeddedL( aSharableFile,aDataType, aParamList) |
|
399 // leaves with KErrInUse which results into immediate close |
|
400 // of image viewer. |
|
401 |
|
402 RFile sharableFile; |
|
403 TRAPD( err, iDocumentHandler->OpenTempFileL( |
|
404 *iFilePath, sharableFile ) ); |
|
405 |
|
406 if ( err == KErrNone ) |
|
407 { |
|
408 CleanupClosePushL( sharableFile ); |
|
409 |
|
410 // Create a param list to remove |
|
411 // the "Use image as" sub menu item |
|
412 CAiwGenericParamList* paramList = CAiwGenericParamList::NewLC(); |
|
413 paramList->Reset(); |
|
414 |
|
415 // Append a param into the list to restrict the viewer application from |
|
416 // showing the "use image as" sub menu item. Currently there is no |
|
417 // AiwGenericParam for this. A CR has been created for AIW to add this |
|
418 // constant to "AiwGenericParam.hrh". |
|
419 // Example: This is how the "Save" menu item is allowed. |
|
420 // paramList->AppendL( EGenericParamAllowSave ); |
|
421 |
|
422 TDataType dataType = TDataType(); |
|
423 |
|
424 __LOG( "Open document now... " ); |
|
425 |
|
426 TRAP( err, err = iDocumentHandler->OpenFileEmbeddedL( |
|
427 sharableFile, dataType, *paramList ) ); |
|
428 |
|
429 __LOG1( "err, err = iDocumentHandler->OpenFileEmbeddedL %d", |
|
430 err ); |
|
431 |
|
432 // Cleanup |
|
433 CleanupStack::PopAndDestroy( paramList ); |
|
434 CleanupStack::PopAndDestroy( &sharableFile ); |
|
435 } |
|
436 |
|
437 if( KErrNone != err) |
|
438 { |
|
439 iFs.Delete( *iFilePath ); |
|
440 iExitReason = err; |
|
441 } |
|
442 } |
|
443 else |
|
444 { |
|
445 iExitReason = KErrNoMemory; |
|
446 } |
|
447 } |
|
448 else |
|
449 { |
|
450 iExitReason = aError; |
|
451 } |
|
452 |
|
453 |
|
454 iCommonUI.HandleCommonErrorL( iExitReason, 0 ); |
|
455 |
|
456 __LOG( "CUPnPLocalPlayer::CopyCompleteL end" ); |
|
457 } |
|
458 |
|
459 // -------------------------------------------------------------------------- |
|
460 // CUPnPLocalPlayer::MediaServerDisappeared |
|
461 // Returns from UPnP AV control point when a media server disppears |
|
462 // -------------------------------------------------------------------------- |
|
463 void CUPnPLocalPlayer::MediaServerDisappeared( |
|
464 TUPnPDeviceDisconnectedReason aReason ) |
|
465 { |
|
466 __LOG( "CUPnPLocalPlayer::MediaServerDisappeared" ); |
|
467 TInt error = KErrNone; |
|
468 if( aReason == EDisconnected ) |
|
469 { |
|
470 error = KErrSessionClosed; |
|
471 } |
|
472 else if( aReason == EWLANLost) |
|
473 { |
|
474 error = KErrDisconnected; |
|
475 } |
|
476 else |
|
477 { |
|
478 __PANICD( __FILE__, __LINE__); |
|
479 } |
|
480 iExitReason = error; |
|
481 FinishNote(); |
|
482 __LOG1("CUPnPLocalPlayer::MediaServerDisappeared %d END",error ); |
|
483 } |
|
484 |
|
485 // -------------------------------------------------------------------------- |
|
486 // CUPnPLocalPlayer::HandleServerAppExit |
|
487 // Returns from application server after quitting a application |
|
488 // here is either image player or video player or music player |
|
489 // -------------------------------------------------------------------------- |
|
490 void CUPnPLocalPlayer::HandleServerAppExit( TInt aReason ) |
|
491 { |
|
492 __LOG1( "CUPnPLocalPlayer::HandleServerAppExit %d" , aReason ); |
|
493 |
|
494 if( iFilePath ) |
|
495 { |
|
496 iFs.Delete( *iFilePath ); |
|
497 } |
|
498 |
|
499 __LOG( "CUPnPLocalPlayer::HandleServerAppExit" ); |
|
500 } |
|
501 |
|
502 // -------------------------------------------------------------------------- |
|
503 // CUPnPLocalPlayer::DialogDismissedL |
|
504 // Returns from dialog server after cancelling a dialog |
|
505 // here is the wait note |
|
506 // -------------------------------------------------------------------------- |
|
507 void CUPnPLocalPlayer::DialogDismissedL( TInt aButtonId ) |
|
508 { |
|
509 __LOG1( "CUPnPLocalPlayer::DialogDismissedL %d", aButtonId ); |
|
510 if( aButtonId == EEikBidCancel ) |
|
511 { |
|
512 iDownloadSession->CancelAllTransfers(); |
|
513 iDownloadSession->RemoveObserver(); |
|
514 if( iBrowseSessionObserver ) |
|
515 { |
|
516 iBrowseSession->SetObserver( *iBrowseSessionObserver ); |
|
517 } |
|
518 iBrowseSessionObserver = NULL; |
|
519 iExitReason = KErrCancel; |
|
520 __LOG( "CUPnPLocalPlayer::DialogDismissedL Cancel " ); |
|
521 |
|
522 } |
|
523 __LOG( "CUPnPLocalPlayer::DialogDismissedL" ); |
|
524 } |
|
525 |
|
526 // -------------------------------------------------------------------------- |
|
527 // CUPnPLocalPlayer::FinishNote |
|
528 // Finish the current waiting note and ready to quit the local playback |
|
529 // -------------------------------------------------------------------------- |
|
530 void CUPnPLocalPlayer::FinishNote() |
|
531 { |
|
532 __LOG( "CUPnPLocalPlayer::FinishNote" ); |
|
533 iDownloadSession->CancelAllTransfers(); |
|
534 iDownloadSession->RemoveObserver(); |
|
535 if( iBrowseSessionObserver ) |
|
536 { |
|
537 iBrowseSession->SetObserver( *iBrowseSessionObserver ); |
|
538 } |
|
539 iBrowseSessionObserver = NULL; |
|
540 if( iWaitNoteDialog ) |
|
541 { |
|
542 TRAP_IGNORE( iWaitNoteDialog->ProcessFinishedL() ); |
|
543 delete iWaitNoteDialog; |
|
544 iWaitNoteDialog = NULL; |
|
545 } |
|
546 __LOG( "CUPnPLocalPlayer::FinishNote-END" ); |
|
547 } |
|
548 |
|
549 // -------------------------------------------------------------------------- |
|
550 // CUPnPLocalPlayer::StartWaitingNoteL |
|
551 // Start the current waiting note |
|
552 // -------------------------------------------------------------------------- |
|
553 void CUPnPLocalPlayer::StartWaitingNoteL() |
|
554 { |
|
555 iWaitNoteDialog = new ( ELeave )CAknWaitDialog( |
|
556 ( REINTERPRET_CAST ( CEikDialog**, &iWaitNoteDialog ) ), |
|
557 ETrue); |
|
558 iWaitNoteDialog->SetCallback( this ); |
|
559 iWaitNoteDialog->ExecuteLD( |
|
560 R_UPNPCOMMONUI_VIDEO_PLAYBACK_WAIT_NOTE_DIALOG ); |
|
561 } |
|
562 |
|
563 // -------------------------------------------------------------------------- |
|
564 // CUPnPLocalPlayer::IsLocallySupportedL |
|
565 // Checks if the item can be played locally. |
|
566 // -------------------------------------------------------------------------- |
|
567 TBool CUPnPLocalPlayer::IsLocallySupportedL( CUpnpObject& aItem ) |
|
568 { |
|
569 TBool retval = EFalse; // return value |
|
570 |
|
571 // Get all res elements into array |
|
572 RUPnPElementsArray elms; |
|
573 CleanupClosePushL( elms ); |
|
574 UPnPItemUtility::GetResElements( aItem, elms ); |
|
575 TInt count = elms.Count(); |
|
576 |
|
577 CUpnpDlnaProtocolInfo* pInfo = NULL; |
|
578 |
|
579 // Determine which resources are usable: |
|
580 // 1. Filter out other than HTTP GET resources (internal uri's, RTP) |
|
581 // 2. Filter out such resources for which DLNA profile is not supported. |
|
582 // 3. Filter out such resources for which mime type is not supported. |
|
583 for( TInt i = count-1 ; i >= 0; i-- ) |
|
584 { |
|
585 // Make sure that it is a HTTP GET resource. Otherwise remove it and |
|
586 // continue with the next one. |
|
587 if( elms[ i ]->Value().Left( |
|
588 KHttpDes.iTypeLength ).Compare( KHttpDes() ) != 0 ) |
|
589 { |
|
590 CUpnpElement* destroyable = elms[i]; |
|
591 aItem.RemoveElementL( destroyable ); |
|
592 delete destroyable; |
|
593 |
|
594 continue; |
|
595 } |
|
596 |
|
597 // Obtain protocolInfo of the res element. |
|
598 const CUpnpAttribute* attr = NULL; |
|
599 TRAPD( nosuchattribute, |
|
600 attr = &UPnPItemUtility::FindAttributeByNameL( |
|
601 *elms[ i ], |
|
602 KProtocolInfo() ) ); |
|
603 |
|
604 if ( nosuchattribute ) |
|
605 { |
|
606 // No mandatory protocolinfo attribute. Remove this and continue. |
|
607 CUpnpElement* destroyable = elms[i]; |
|
608 aItem.RemoveElementL( destroyable ); |
|
609 delete destroyable; |
|
610 |
|
611 continue; |
|
612 } |
|
613 |
|
614 // parse protocol info |
|
615 pInfo = CUpnpDlnaProtocolInfo::NewL( attr->Value() ); |
|
616 CleanupStack::PushL( pInfo ); |
|
617 |
|
618 // Check that DLNA profile is among the supported ones. |
|
619 if ( pInfo->PnParameter() != KNullDesC8() |
|
620 && !UPnPDlnaUtility::IsSupportedDlnaProfile( |
|
621 pInfo->PnParameter() ) ) |
|
622 { |
|
623 // DLNA profile not supported. Remove this and continue. |
|
624 CUpnpElement* destroyable = elms[i]; |
|
625 aItem.RemoveElementL( destroyable ); |
|
626 delete destroyable; |
|
627 CleanupStack::PopAndDestroy( pInfo ); |
|
628 pInfo = NULL; |
|
629 |
|
630 continue; |
|
631 } |
|
632 |
|
633 // check that mime type is among the supported ones |
|
634 TPtrC8 mime = pInfo->ThirdField(); |
|
635 if ( !UPnPDlnaUtility::IsSupportedMimeType( mime ) ) |
|
636 { |
|
637 // mime type not supported. |
|
638 TPtrC8 httpget = pInfo->FirstField(); |
|
639 TPtrC8 httpdlnatem = pInfo->FourthField(); |
|
640 HBufC8* tem = NULL; |
|
641 tem = httpdlnatem.Right( httpdlnatem.Length() - httpdlnatem.Find( |
|
642 KHttpEqual ) - 1 ).AllocLC(); |
|
643 tem->Des().Trim(); |
|
644 TPtrC8 httpdlna = *tem; |
|
645 CleanupStack::PopAndDestroy( tem ); |
|
646 if ( httpget.Compare( KHttpGetDes ) != 0 || |
|
647 !UPnPDlnaUtility::IsSupportedDlnaProfile |
|
648 ( httpdlna ) ) |
|
649 { |
|
650 // mime type not supported and DLNA profile not supported. |
|
651 // Remove this and continue |
|
652 CUpnpElement* destroyable = elms[i]; |
|
653 aItem.RemoveElementL( destroyable ); |
|
654 delete destroyable; |
|
655 CleanupStack::PopAndDestroy( pInfo ); |
|
656 pInfo = NULL; |
|
657 |
|
658 continue; |
|
659 } |
|
660 } |
|
661 |
|
662 CleanupStack::PopAndDestroy( pInfo ); |
|
663 pInfo = NULL; |
|
664 } |
|
665 |
|
666 // All res elements have been processed and removed if they are not |
|
667 // supported. Clean up and return ETrue if there are res elements |
|
668 // left in the item and EFalse if there are no res elements left. |
|
669 CleanupStack::PopAndDestroy( &elms ); |
|
670 |
|
671 UPnPItemUtility::GetResElements( aItem, elms ); |
|
672 retval = elms.Count(); |
|
673 elms.Close(); |
|
674 |
|
675 return retval; |
|
676 } |
|
677 |
|
678 |
|
679 // End of File |
|