|
1 /* |
|
2 * Copyright (c) 2006 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: playlist engine |
|
15 * |
|
16 * CMPXPlaylistEngine contains a CMPXPlaylistPluginHandler and a task queue. |
|
17 * CMPXPlaylistEngine uses CMPXPlaylistPluginHandler to select an appropriate |
|
18 * playlist plugin to handle the client's requests. It's also used for querying |
|
19 * about the currently loaded playlist plugin. |
|
20 * |
|
21 * The task queue is used to manage async requests submitted by the client. |
|
22 * When an InternalizePlaylistL or ExternalizePlaylistL request is received, |
|
23 * it's added to the task queue. When a task in the queue is ready for |
|
24 * execution, ExecuteTask is called. To process the task, CMPXPlaylistEngine |
|
25 * will select an appropriate plugin; once one is found, the request is |
|
26 * handed over to the plugin and CMPXPlaylistEngine becomes active. Before |
|
27 * the plugin completes the request, CMPXPlaylistEngine is notified of the |
|
28 * results through MMPXPlaylistPluginObserver interface; CMPXPlaylistEngine |
|
29 * passes the results to its client through MMPXPlaylistEngineObserver |
|
30 * interface. Once CMPXPlaylistEngine's client completes the handling of the |
|
31 * results, plugin completes the request and CMPXPlaylistEngine::RunL |
|
32 * is called to complete one task processing cycle. CMPXPlaylistEngine is |
|
33 * ready to process the next task if any at the completion of RunL. |
|
34 * |
|
35 * DESIGN DECISION: |
|
36 * Only one task queue is used instead of one per plugin because this is |
|
37 * running on the client thread. No processing time gained for having |
|
38 * separate task queues. |
|
39 * |
|
40 * |
|
41 */ |
|
42 |
|
43 #include <s32mem.h> |
|
44 #include <bamdesca.h> |
|
45 #include <badesca.h> |
|
46 #include <bautils.h> |
|
47 #include <uri16.h> |
|
48 #include <apmrec.h> |
|
49 #include <syslangutil.h> |
|
50 #include <languages.hrh> |
|
51 #include <data_caging_path_literals.hrh> |
|
52 #include <mpxplaylisttopcharacterset.rsg> |
|
53 #include <mpxlog.h> |
|
54 #include <mpxtaskqueue.h> |
|
55 #include <mpxmedia.h> |
|
56 #include <mpxmediaarray.h> |
|
57 #include <mpxmediageneraldefs.h> |
|
58 #include <mpxmediacontainerdefs.h> |
|
59 #include "mpxplaylistenginedefs.hrh" |
|
60 #include "mpxplaylistplugin.h" |
|
61 #include "mpxplaylistengine.h" |
|
62 #include "mpxplaylistrecognizer.h" |
|
63 |
|
64 // ============================ CONSTANTS ===================================== |
|
65 const TInt KMPXBufExpandSize = 0x40; |
|
66 const TInt KMPXArrayGranularity = 12; |
|
67 _LIT( KMPXPlaylistEnginePanic, "CMPXPlaylistEngine"); |
|
68 _LIT(KMPXPlaylistCharacterSetRscFile, "mpxplaylisttopcharacterset.rsc"); |
|
69 _LIT( KMPXPlaylistExtension, ".m3u" ); |
|
70 |
|
71 // ============================ MEMBER FUNCTIONS ============================== |
|
72 // ---------------------------------------------------------------------------- |
|
73 // Constructor. |
|
74 // ---------------------------------------------------------------------------- |
|
75 // |
|
76 CMPXPlaylistEngine::CMPXPlaylistEngine( |
|
77 MMPXPlaylistEngineObserver& aObserver) |
|
78 : CActive(EPriorityStandard), |
|
79 iObserver(aObserver) |
|
80 { |
|
81 CActiveScheduler::Add(this); |
|
82 } |
|
83 |
|
84 // ---------------------------------------------------------------------------- |
|
85 // 2nd phase constructor. |
|
86 // ---------------------------------------------------------------------------- |
|
87 // |
|
88 void CMPXPlaylistEngine::ConstructL() |
|
89 { |
|
90 User::LeaveIfError(iFs.Connect()); |
|
91 iCharacterSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs); |
|
92 iTopCharacterSet = |
|
93 new (ELeave)CArrayFixFlat<CCnvCharacterSetConverter::SCharacterSet>(KMPXArrayGranularity); |
|
94 GenerateTopCharacterSetsL(); |
|
95 |
|
96 iTaskQueue = CMPXActiveTaskQueue::NewL(); |
|
97 iPluginHandler = CMPXPlaylistPluginHandler::NewL( |
|
98 *this, *this, iFs, *iTopCharacterSet, *iCharacterSet); |
|
99 } |
|
100 |
|
101 // ---------------------------------------------------------------------------- |
|
102 // Two-phased constructor. |
|
103 // ---------------------------------------------------------------------------- |
|
104 // |
|
105 EXPORT_C CMPXPlaylistEngine* CMPXPlaylistEngine::NewL( |
|
106 MMPXPlaylistEngineObserver& aObserver) |
|
107 { |
|
108 CMPXPlaylistEngine* self=new(ELeave)CMPXPlaylistEngine(aObserver); |
|
109 CleanupStack::PushL(self); |
|
110 self->ConstructL(); |
|
111 CleanupStack::Pop(self); |
|
112 return self; |
|
113 } |
|
114 |
|
115 // ---------------------------------------------------------------------------- |
|
116 // Destructor. |
|
117 // ---------------------------------------------------------------------------- |
|
118 // |
|
119 EXPORT_C CMPXPlaylistEngine::~CMPXPlaylistEngine() |
|
120 { |
|
121 Cancel(); |
|
122 Cleanup(); |
|
123 |
|
124 iFs.Close(); |
|
125 delete iTaskQueue; |
|
126 delete iPluginHandler; |
|
127 delete iCharacterSet; |
|
128 delete iTopCharacterSet; |
|
129 iRscFile.Close(); |
|
130 } |
|
131 |
|
132 // =========================== EXTERNAL FUNCTIONS ============================= |
|
133 // ---------------------------------------------------------------------------- |
|
134 // Return a handle to playlist plugin handler |
|
135 // ---------------------------------------------------------------------------- |
|
136 EXPORT_C CMPXPlaylistPluginHandler& CMPXPlaylistEngine::PlaylistPluginHandler() |
|
137 { |
|
138 ASSERT( iPluginHandler ); |
|
139 return *iPluginHandler; |
|
140 } |
|
141 |
|
142 // ---------------------------------------------------------------------------- |
|
143 // Determines whether the given media is a playlist |
|
144 // Currently, Music Player only supports m3u playlist. |
|
145 // ---------------------------------------------------------------------------- |
|
146 // |
|
147 EXPORT_C TBool CMPXPlaylistEngine::IsPlaylistL( const TDesC& aUri ) |
|
148 { |
|
149 // Check if the file extension is ".m3u". |
|
150 TBool isPlaylist = EFalse; |
|
151 TParsePtrC parse( aUri ); |
|
152 if ( !parse.Ext().CompareF( KMPXPlaylistExtension ) ) |
|
153 { |
|
154 isPlaylist = ETrue; |
|
155 } |
|
156 |
|
157 return isPlaylist; |
|
158 } |
|
159 |
|
160 // ---------------------------------------------------------------------------- |
|
161 // Internalize a playlist (async) |
|
162 // |
|
163 // Add the request to the task queue |
|
164 // ---------------------------------------------------------------------------- |
|
165 EXPORT_C void CMPXPlaylistEngine::InternalizePlaylistL(const TDesC& aPlaylistUri) |
|
166 { |
|
167 MPX_DEBUG1("CMPXPlaylistEngine::InternalizePlaylistL"); |
|
168 |
|
169 // |
|
170 // leave if the given file does not exist |
|
171 // |
|
172 if (!BaflUtils::FileExists(iFs, aPlaylistUri)) |
|
173 { |
|
174 User::Leave( KErrNotFound ); |
|
175 } |
|
176 |
|
177 // |
|
178 // externalize parameters |
|
179 // |
|
180 CBufBase* taskParam = CBufFlat::NewL( KMPXBufExpandSize ); |
|
181 CleanupStack::PushL( taskParam ); |
|
182 taskParam->ResizeL( KMPXBufExpandSize ); |
|
183 |
|
184 RBufWriteStream writeStream( *taskParam ); |
|
185 CleanupClosePushL( writeStream ); |
|
186 |
|
187 // externalize playlist URI |
|
188 writeStream.WriteInt32L( aPlaylistUri.Length() ); |
|
189 writeStream << aPlaylistUri; |
|
190 |
|
191 writeStream.CommitL(); |
|
192 taskParam->Compress(); |
|
193 |
|
194 // |
|
195 // add request to the task queue |
|
196 // |
|
197 iTaskQueue->AddTaskL( EInternalizePlaylist, |
|
198 NULL, // callback when task completed |
|
199 this, // task queue observer |
|
200 0, // Integer parameter, not used |
|
201 taskParam ); // task queue assumes ownership of taskParam |
|
202 |
|
203 CleanupStack::PopAndDestroy( &writeStream ); |
|
204 CleanupStack::Pop( taskParam ); // taskParam |
|
205 } |
|
206 |
|
207 // ---------------------------------------------------------------------------- |
|
208 // Internalize a playlist (async) |
|
209 // ---------------------------------------------------------------------------- |
|
210 EXPORT_C void CMPXPlaylistEngine::InternalizePlaylistL(const RFile& aPlaylistFileHandle) |
|
211 { |
|
212 MPX_DEBUG1("CMPXPlaylistEngine::InternalizePlaylistL"); |
|
213 |
|
214 if ( !aPlaylistFileHandle.SubSessionHandle() ) |
|
215 { |
|
216 User::Leave(KErrArgument); |
|
217 } |
|
218 |
|
219 TFileName fullName; |
|
220 aPlaylistFileHandle.FullName( fullName ); |
|
221 |
|
222 InternalizePlaylistL( fullName ); |
|
223 } |
|
224 |
|
225 // ---------------------------------------------------------------------------- |
|
226 // Externalize a playlist (async) |
|
227 // |
|
228 // Add the request to the task queue |
|
229 // ---------------------------------------------------------------------------- |
|
230 EXPORT_C void CMPXPlaylistEngine::ExternalizePlaylistL( |
|
231 const CMPXMedia& aPlaylist, |
|
232 const TDesC& aFilePath) |
|
233 { |
|
234 MPX_DEBUG1("CMPXPlaylistEngine::ExternalizePlaylistL"); |
|
235 |
|
236 // |
|
237 // leave if the given playlist doesn't contain the following attributes |
|
238 // |
|
239 if (!aPlaylist.IsSupported(KMPXMediaGeneralTitle) || |
|
240 !aPlaylist.IsSupported(KMPXMediaGeneralType) || |
|
241 !aPlaylist.IsSupported(KMPXMediaGeneralCategory) || |
|
242 !aPlaylist.IsSupported(KMPXMediaArrayContents) || |
|
243 !aPlaylist.IsSupported(KMPXMediaArrayCount)) |
|
244 { |
|
245 User::Leave( KErrArgument ); |
|
246 } |
|
247 |
|
248 // |
|
249 // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category |
|
250 // must be EMPXPlaylist |
|
251 // |
|
252 TMPXGeneralType mediaType = |
|
253 aPlaylist.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType); |
|
254 |
|
255 TMPXGeneralCategory mediaCategory = |
|
256 aPlaylist.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory); |
|
257 |
|
258 if ( mediaType != EMPXItem || |
|
259 mediaCategory != EMPXPlaylist ) |
|
260 { |
|
261 User::Leave( KErrArgument ); |
|
262 } |
|
263 |
|
264 // |
|
265 // leave if the given file path does not exist |
|
266 // |
|
267 if (!BaflUtils::PathExists(iFs, aFilePath)) |
|
268 { |
|
269 User::Leave( KErrPathNotFound ); |
|
270 } |
|
271 |
|
272 // check if a plugin has been selected. the client |
|
273 // is required to select a plugin before issuing |
|
274 // this request |
|
275 if ( !iPluginHandler->PluginFound() ) |
|
276 { |
|
277 User::Leave( KErrNotFound ); |
|
278 } |
|
279 |
|
280 // |
|
281 // externalize parameters |
|
282 // |
|
283 CBufBase* taskParam = CBufFlat::NewL( KMPXBufExpandSize ); |
|
284 CleanupStack::PushL( taskParam ); |
|
285 taskParam->ResizeL( KMPXBufExpandSize ); |
|
286 |
|
287 RBufWriteStream writeStream( *taskParam ); |
|
288 CleanupClosePushL( writeStream ); |
|
289 |
|
290 // externalize playlist |
|
291 writeStream << aPlaylist; |
|
292 |
|
293 // externalize file path |
|
294 writeStream.WriteInt32L( aFilePath.Length() ); |
|
295 writeStream << aFilePath; |
|
296 |
|
297 // externalize plugin Uid |
|
298 writeStream.WriteInt32L( iPluginHandler->PluginUid().iUid ); |
|
299 |
|
300 writeStream.CommitL(); |
|
301 taskParam->Compress(); |
|
302 |
|
303 // |
|
304 // add request to the task queue |
|
305 // |
|
306 CMPXMedia* playlist = CMPXMedia::NewL(aPlaylist); |
|
307 CleanupStack::PushL(playlist); |
|
308 |
|
309 iTaskQueue->AddTaskL( EExternalizePlaylist, |
|
310 NULL, // callback when task completed |
|
311 this, // task queue observer |
|
312 0, // Integer parameter, not used |
|
313 taskParam, // task queue assumes ownership |
|
314 NULL, |
|
315 playlist ); // keep media alive. ownership transferred |
|
316 |
|
317 CleanupStack::Pop( playlist ); |
|
318 CleanupStack::PopAndDestroy( &writeStream ); |
|
319 CleanupStack::Pop( taskParam ); // taskParam |
|
320 } |
|
321 |
|
322 // ---------------------------------------------------------------------------- |
|
323 // Cancel Requests |
|
324 // ---------------------------------------------------------------------------- |
|
325 EXPORT_C void CMPXPlaylistEngine::CancelRequests() |
|
326 { |
|
327 MPX_DEBUG1("CMPXPlaylistEngine::CancelRequests"); |
|
328 Cancel(); |
|
329 iTaskQueue->CancelRequests(); |
|
330 } |
|
331 |
|
332 // =========================== CALLBACK FUNCTIONS ============================= |
|
333 // ---------------------------------------------------------------------------- |
|
334 // Handles plugin callback for InternalizePlaylistL request |
|
335 // ---------------------------------------------------------------------------- |
|
336 void CMPXPlaylistEngine::HandlePlaylistL( |
|
337 CMPXMedia* aPlaylist, |
|
338 const TInt aError, |
|
339 const TBool aCompleted) |
|
340 { |
|
341 MPX_DEBUG1("CMPXPlaylistEngine::HandlePlaylistL"); |
|
342 |
|
343 // notify playlist engine observer |
|
344 iObserver.HandlePlaylistL( aPlaylist, aError, aCompleted ); |
|
345 } |
|
346 |
|
347 // ---------------------------------------------------------------------------- |
|
348 // Handle plugin callback for ExternalizePlaylistL request |
|
349 // ---------------------------------------------------------------------------- |
|
350 void CMPXPlaylistEngine::HandlePlaylistL( |
|
351 const TDesC& aPlaylistUri, |
|
352 const TInt aError) |
|
353 { |
|
354 MPX_DEBUG1("CMPXPlaylistEngine::HandlePlaylistL"); |
|
355 |
|
356 // notify playlist engine observer |
|
357 iObserver.HandlePlaylistL( aPlaylistUri, aError ); |
|
358 } |
|
359 |
|
360 // =========================== INTERNAL FUNCTIONS ============================= |
|
361 // ---------------------------------------------------------------------------- |
|
362 // Handles request completion event |
|
363 // ---------------------------------------------------------------------------- |
|
364 // |
|
365 void CMPXPlaylistEngine::RunL() |
|
366 { |
|
367 MPX_DEBUG2("CMPXPlaylistEngine::RunL - status %d", iStatus.Int()); |
|
368 |
|
369 // clean up data set during processing of the current task |
|
370 Cleanup(); |
|
371 |
|
372 // we are done with the current request and ready for the next one if there is |
|
373 // any |
|
374 iTaskQueue->CompleteTask(); |
|
375 } |
|
376 |
|
377 // ---------------------------------------------------------------------------- |
|
378 // Cancellation of an outstanding request. |
|
379 // ---------------------------------------------------------------------------- |
|
380 // |
|
381 void CMPXPlaylistEngine::DoCancel() |
|
382 { |
|
383 if ( iPluginHandler->PluginFound() ) |
|
384 { |
|
385 iPluginHandler->Plugin()->Cancel(); |
|
386 } |
|
387 Cleanup(); |
|
388 iTaskQueue->CompleteTask(); |
|
389 } |
|
390 |
|
391 // ---------------------------------------------------------------------------- |
|
392 // Execute an async task |
|
393 // ---------------------------------------------------------------------------- |
|
394 // |
|
395 void CMPXPlaylistEngine::ExecuteTask( |
|
396 TInt aTask, |
|
397 TInt /*aParamData*/, |
|
398 TAny* /*aPtrData*/, |
|
399 const CBufBase& aBuf, |
|
400 TAny* /*aCallback*/, |
|
401 CBase* /*aCObject1*/, |
|
402 CBase* /*aCObject2*/) |
|
403 { |
|
404 TRAPD(err, ExecuteTaskL(aTask, aBuf)); |
|
405 if (err != KErrNone) |
|
406 { |
|
407 HandleExecuteTaskError(aTask, err); |
|
408 } |
|
409 } |
|
410 |
|
411 // ---------------------------------------------------------------------------- |
|
412 // CMPXPlaylistEngine::HandleTaskError |
|
413 // ---------------------------------------------------------------------------- |
|
414 // |
|
415 void CMPXPlaylistEngine::HandleTaskError( |
|
416 TInt /* aTask */, |
|
417 TAny* /*aPtrData*/, |
|
418 TAny* /*aCallback*/, |
|
419 TInt /* aError */) |
|
420 { |
|
421 // do nothing |
|
422 } |
|
423 |
|
424 // ---------------------------------------------------------------------------- |
|
425 // CMPXPlaylistEngine::HandlePluginHandlerEvent |
|
426 // ---------------------------------------------------------------------------- |
|
427 // |
|
428 void CMPXPlaylistEngine::HandlePluginHandlerEvent( |
|
429 TPluginHandlerEvents /* aEvent */, |
|
430 const TUid& /* aPluginUid */, |
|
431 TBool /* aLoaded */, |
|
432 TInt /* aData */) |
|
433 { |
|
434 // Playlist plugins are stateless and they are resolved for every call. |
|
435 // There is no need to cancel the existing queued requests in case the |
|
436 // plugin is updated as the new version of the plugin is expected to handle |
|
437 // these calls the same as the previous version did. |
|
438 // |
|
439 // In case the plugin is removed it is expected that all queued ResolvePluginL |
|
440 // calls will leave with KErrNotSupported, which will be sent to the caller. |
|
441 } |
|
442 |
|
443 // ---------------------------------------------------------------------------- |
|
444 // Execute an async task. Leaves when an error is encountered. |
|
445 // ---------------------------------------------------------------------------- |
|
446 // |
|
447 void CMPXPlaylistEngine::ExecuteTaskL(TInt aTask, const CBufBase& aBuf) |
|
448 { |
|
449 __ASSERT_ALWAYS( !IsActive(), User::Panic(KMPXPlaylistEnginePanic, KErrInUse) ); |
|
450 |
|
451 RBufReadStream readStream( aBuf ); |
|
452 CleanupClosePushL( readStream ); |
|
453 |
|
454 switch( aTask ) |
|
455 { |
|
456 case EInternalizePlaylist: |
|
457 { |
|
458 // internalize playlist parameter |
|
459 iPlaylistUri = HBufC::NewL( readStream, readStream.ReadInt32L() ); |
|
460 |
|
461 // automatically select a plugin that is capable of handling |
|
462 // the specified media file. SelectPlaylistPluginL leaves |
|
463 // with KErrNotSupported when an appropriate plugin cannot |
|
464 // be found |
|
465 iPluginHandler->SelectPlaylistPluginL( *iPlaylistUri, KNullDesC8 ); |
|
466 |
|
467 // an appropriate plugin is found, issue the request to the |
|
468 // selected plugin |
|
469 iPluginHandler->Plugin()->InternalizePlaylistL( iStatus, *iPlaylistUri ); |
|
470 } |
|
471 break; |
|
472 |
|
473 case EExternalizePlaylist: |
|
474 { |
|
475 // internalize playlist |
|
476 iPlaylist = CMPXMedia::NewL(); |
|
477 readStream >> *iPlaylist; |
|
478 |
|
479 // internalize file path |
|
480 iFilePath = HBufC::NewL( readStream, readStream.ReadInt32L() ); |
|
481 |
|
482 // internalize plugin Uid |
|
483 TUid pluginUid = TUid::Uid( readStream.ReadInt32L() ); |
|
484 |
|
485 // |
|
486 // select the specified plugin. When the specified plugin |
|
487 // cannot be found, SelectPlaylistPluginL will leave with |
|
488 // KErrNotSupported error code. |
|
489 // |
|
490 // Possible scenario: |
|
491 // The specified plugin is available when the client made |
|
492 // the selection before issuing the request, but the plugin |
|
493 // has since been uninstalled when we are ready to process |
|
494 // this request. |
|
495 // |
|
496 iPluginHandler->SelectPlaylistPluginL( pluginUid ); |
|
497 |
|
498 // found the specified plugin, issue the request |
|
499 iPluginHandler->Plugin()->ExternalizePlaylistL( |
|
500 iStatus, *iPlaylist, *iFilePath ); |
|
501 } |
|
502 break; |
|
503 |
|
504 // |
|
505 // command not supported |
|
506 // |
|
507 default: |
|
508 { |
|
509 ASSERT(0); |
|
510 break; |
|
511 } |
|
512 } |
|
513 |
|
514 CleanupStack::PopAndDestroy( &readStream ); // readStream |
|
515 |
|
516 SetActive(); |
|
517 } |
|
518 |
|
519 // ---------------------------------------------------------------------------- |
|
520 // Handles a leave occurring in the request completion event handler ExecuteTaskL |
|
521 // ---------------------------------------------------------------------------- |
|
522 // |
|
523 void CMPXPlaylistEngine::HandleExecuteTaskError(TInt aTask, TInt aError) |
|
524 { |
|
525 TRAP_IGNORE(HandleExecuteTaskErrorL(aTask, aError)); |
|
526 |
|
527 // clean up data set during processing of the current task |
|
528 Cleanup(); |
|
529 |
|
530 // although an error has occured while processing the current task, we are |
|
531 // done with the current request and ready for the next one if there is |
|
532 // any |
|
533 iTaskQueue->CompleteTask(); |
|
534 } |
|
535 |
|
536 // ---------------------------------------------------------------------------- |
|
537 // Handles a leave occurring in the request completion event handler ExecuteTaskL |
|
538 // ---------------------------------------------------------------------------- |
|
539 // |
|
540 void CMPXPlaylistEngine::HandleExecuteTaskErrorL(TInt aTask, TInt aError) |
|
541 { |
|
542 MPX_DEBUG3("CMPXPlaylistEngine::HandleExecuteTaskErrorL(task %d, error %d)", aTask, aError); |
|
543 |
|
544 // |
|
545 // notify client |
|
546 // |
|
547 switch (aTask) |
|
548 { |
|
549 case EInternalizePlaylist: |
|
550 { |
|
551 iObserver.HandlePlaylistL( NULL, aError, ETrue ); |
|
552 } |
|
553 break; |
|
554 |
|
555 case EExternalizePlaylist: |
|
556 { |
|
557 const TDesC& playlist = |
|
558 iPlaylist? iPlaylist->ValueText(KMPXMediaGeneralTitle) : KNullDesC; |
|
559 |
|
560 iObserver.HandlePlaylistL( playlist, aError ); |
|
561 } |
|
562 break; |
|
563 |
|
564 default: |
|
565 { |
|
566 ASSERT(0); |
|
567 break; |
|
568 } |
|
569 } |
|
570 } |
|
571 |
|
572 // ---------------------------------------------------------------------------- |
|
573 // cleanup |
|
574 // ---------------------------------------------------------------------------- |
|
575 // |
|
576 void CMPXPlaylistEngine::Cleanup() |
|
577 { |
|
578 delete iPlaylistUri; |
|
579 iPlaylistUri = NULL; |
|
580 |
|
581 delete iFilePath; |
|
582 iFilePath = NULL; |
|
583 |
|
584 delete iPlaylist; |
|
585 iPlaylist = NULL; |
|
586 } |
|
587 |
|
588 // ----------------------------------------------------------------------------- |
|
589 // CMPXPlaylistEngine::GenerateTopCharacterSets() |
|
590 // ----------------------------------------------------------------------------- |
|
591 // |
|
592 void CMPXPlaylistEngine::GenerateTopCharacterSetsL() |
|
593 { |
|
594 CArrayFixFlat<TInt>* installedLanguages = NULL; |
|
595 SysLangUtil::GetInstalledLanguages(installedLanguages); |
|
596 CleanupStack::PushL(installedLanguages); |
|
597 |
|
598 |
|
599 TParse* fp = new(ELeave) TParse(); |
|
600 fp->Set(KMPXPlaylistCharacterSetRscFile, &KDC_RESOURCE_FILES_DIR, NULL); |
|
601 CleanupStack::PushL(fp); |
|
602 |
|
603 TFileName resourceFile = fp->FullName(); |
|
604 User::LeaveIfError( MPXUser::CompleteWithDllPath( resourceFile ) ); |
|
605 |
|
606 // Open the resource file |
|
607 TRAPD(err, iRscFile.OpenL(iFs, resourceFile)); |
|
608 // if there is no resource file, then there is no top character set list |
|
609 if (err) |
|
610 { |
|
611 CleanupStack::PopAndDestroy(2, installedLanguages); |
|
612 return; |
|
613 } |
|
614 |
|
615 for (TInt i=0; i < installedLanguages->Count(); i++) |
|
616 { |
|
617 SelectCharacterSetsForLanguageL(installedLanguages->At(i)); |
|
618 } |
|
619 iTopCharacterSet->Compress(); |
|
620 installedLanguages->Reset(); |
|
621 CleanupStack::PopAndDestroy(2, installedLanguages); |
|
622 iRscFile.Close(); |
|
623 } |
|
624 |
|
625 // ----------------------------------------------------------------------------- |
|
626 // CMetaDataParser::SelectCharacterSetsForLanguage() |
|
627 // ----------------------------------------------------------------------------- |
|
628 // |
|
629 void CMPXPlaylistEngine::SelectCharacterSetsForLanguageL(TInt aLanguage) |
|
630 { |
|
631 switch ( aLanguage ) |
|
632 { |
|
633 case ELangEnglish: |
|
634 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET); |
|
635 break; |
|
636 case ELangFrench: |
|
637 ReadCharacterSetResourceL(R_MPX_PLAYLIST_FRENCH_CHAR_SET); |
|
638 break; |
|
639 case ELangGerman: |
|
640 ReadCharacterSetResourceL(R_MPX_PLAYLIST_GERMAN_CHAR_SET); |
|
641 break; |
|
642 case ELangTurkish: |
|
643 ReadCharacterSetResourceL(R_MPX_PLAYLIST_TURKISH_CHAR_SET); |
|
644 break; |
|
645 case ELangFinnish: |
|
646 ReadCharacterSetResourceL(R_MPX_PLAYLIST_FINNISH_CHAR_SET); |
|
647 break; |
|
648 case ELangSwedish: |
|
649 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SWEDISH_CHAR_SET); |
|
650 break; |
|
651 case ELangRussian: |
|
652 ReadCharacterSetResourceL(R_MPX_PLAYLIST_RUSSIAN_CHAR_SET); |
|
653 break; |
|
654 case ELangArabic: |
|
655 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ARABIC_CHAR_SET); |
|
656 break; |
|
657 case ELangHebrew: |
|
658 ReadCharacterSetResourceL(R_MPX_PLAYLIST_HEBREW_CHAR_SET); |
|
659 break; |
|
660 case ELangFarsi: |
|
661 ReadCharacterSetResourceL(R_MPX_PLAYLIST_FARSI_CHAR_SET); |
|
662 break; |
|
663 case ELangItalian: |
|
664 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ITALIAN_CHAR_SET); |
|
665 break; |
|
666 case ELangPolish: |
|
667 ReadCharacterSetResourceL(R_MPX_PLAYLIST_POLISH_CHAR_SET); |
|
668 break; |
|
669 case ELangHungarian: |
|
670 ReadCharacterSetResourceL(R_MPX_PLAYLIST_HUNGARIAN_CHAR_SET); |
|
671 break; |
|
672 case ELangSpanish: |
|
673 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SPANISH_CHAR_SET); |
|
674 break; |
|
675 case ELangDutch: |
|
676 ReadCharacterSetResourceL(R_MPX_PLAYLIST_DUTCH_CHAR_SET); |
|
677 break; |
|
678 case ELangPortuguese: |
|
679 ReadCharacterSetResourceL(R_MPX_PLAYLIST_PORTUGUESE_CHAR_SET); |
|
680 break; |
|
681 case ELangAmerican: |
|
682 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET); |
|
683 break; |
|
684 case ELangCanadianFrench: |
|
685 ReadCharacterSetResourceL(R_MPX_PLAYLIST_FRENCH_CHAR_SET); |
|
686 break; |
|
687 case ELangBrazilianPortuguese: |
|
688 ReadCharacterSetResourceL(R_MPX_PLAYLIST_PORTUGUESE_CHAR_SET); |
|
689 break; |
|
690 case ELangLatinAmericanSpanish: |
|
691 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SPANISH_CHAR_SET); |
|
692 break; |
|
693 case ELangLatvian: |
|
694 ReadCharacterSetResourceL(R_MPX_PLAYLIST_LATVIAN_CHAR_SET); |
|
695 break; |
|
696 case ELangGreek: |
|
697 ReadCharacterSetResourceL(R_MPX_PLAYLIST_GREEK_CHAR_SET); |
|
698 break; |
|
699 case ELangEstonian: |
|
700 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ESTONIAN_CHAR_SET); |
|
701 break; |
|
702 case ELangLithuanian: |
|
703 ReadCharacterSetResourceL(R_MPX_PLAYLIST_LITHUANIAN_CHAR_SET); |
|
704 break; |
|
705 case ELangRomanian: |
|
706 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ROMANIAN_CHAR_SET); |
|
707 break; |
|
708 case ELangUkrainian: |
|
709 ReadCharacterSetResourceL(R_MPX_PLAYLIST_UKRAINIAN_CHAR_SET); |
|
710 break; |
|
711 case ELangBulgarian: |
|
712 ReadCharacterSetResourceL(R_MPX_PLAYLIST_BULGARIAN_CHAR_SET); |
|
713 break; |
|
714 case ELangCroatian: |
|
715 ReadCharacterSetResourceL(R_MPX_PLAYLIST_CROATIAN_CHAR_SET); |
|
716 break; |
|
717 case ELangSerbian: |
|
718 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SERBIAN_CHAR_SET); |
|
719 break; |
|
720 case ELangIndonesian: |
|
721 ReadCharacterSetResourceL(R_MPX_PLAYLIST_INDONESIAN_CHAR_SET); |
|
722 break; |
|
723 case ELangMalay: |
|
724 case ELangTagalog: |
|
725 ReadCharacterSetResourceL(R_MPX_PLAYLIST_MALAY_CHAR_SET); |
|
726 break; |
|
727 case ELangIcelandic: |
|
728 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ICELANDIC_CHAR_SET); |
|
729 break; |
|
730 case ELangDanish: |
|
731 ReadCharacterSetResourceL(R_MPX_PLAYLIST_DANISH_CHAR_SET); |
|
732 break; |
|
733 case ELangNorwegian: |
|
734 ReadCharacterSetResourceL(R_MPX_PLAYLIST_NORWEGIAN_CHAR_SET); |
|
735 break; |
|
736 case ELangHindi: |
|
737 ReadCharacterSetResourceL(R_MPX_PLAYLIST_INDIAN_CHAR_SET); |
|
738 break; |
|
739 case ELangUrdu: |
|
740 ReadCharacterSetResourceL(R_MPX_PLAYLIST_URDU_CHAR_SET); |
|
741 break; |
|
742 case ELangCzech: |
|
743 ReadCharacterSetResourceL(R_MPX_PLAYLIST_CZECH_CHAR_SET); |
|
744 break; |
|
745 case ELangSlovak: |
|
746 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SLOVAK_CHAR_SET); |
|
747 break; |
|
748 case ELangSlovenian: |
|
749 ReadCharacterSetResourceL(R_MPX_PLAYLIST_SLOVENIAN_CHAR_SET); |
|
750 break; |
|
751 case ELangTaiwanChinese: |
|
752 case ELangHongKongChinese: |
|
753 ReadCharacterSetResourceL(R_MPX_PLAYLIST_TAIWAN_HK_CHINESE_CHAR_SET); |
|
754 break; |
|
755 case ELangPrcChinese: |
|
756 ReadCharacterSetResourceL(R_MPX_PLAYLIST_CHINESE_CHAR_SET); |
|
757 break; |
|
758 case ELangEnglish_Taiwan: |
|
759 case ELangEnglish_Prc: |
|
760 case ELangEnglish_Japan: |
|
761 case ELangEnglish_Thailand: |
|
762 ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET); |
|
763 break; |
|
764 case ELangJapanese: |
|
765 ReadCharacterSetResourceL(R_MPX_PLAYLIST_JAPANESE_CHAR_SET); |
|
766 break; |
|
767 case ELangThai: |
|
768 ReadCharacterSetResourceL(R_MPX_PLAYLIST_THAI_CHAR_SET); |
|
769 break; |
|
770 case ELangVietnamese: |
|
771 ReadCharacterSetResourceL(R_MPX_PLAYLIST_VIETNAMESE_CHAR_SET); |
|
772 break; |
|
773 case ELangMalay_Apac: |
|
774 ReadCharacterSetResourceL(R_MPX_PLAYLIST_MALAY_CHAR_SET); |
|
775 break; |
|
776 default: |
|
777 break; |
|
778 } |
|
779 } |
|
780 |
|
781 // ----------------------------------------------------------------------------- |
|
782 // CMPXPlaylistEngine::ReadCharacterSetResourceL() |
|
783 // ----------------------------------------------------------------------------- |
|
784 // |
|
785 void CMPXPlaylistEngine::ReadCharacterSetResourceL(TInt aResourceId) |
|
786 { |
|
787 TResourceReader rscReader; // Resource reader |
|
788 HBufC8* rscBuf; // Buffer where resource is read |
|
789 |
|
790 rscBuf = iRscFile.AllocReadL(aResourceId); |
|
791 rscReader.SetBuffer(rscBuf); |
|
792 CleanupStack::PushL(rscBuf); |
|
793 |
|
794 TUint characterSetElementId; |
|
795 TInt numCharacterSetElements = rscReader.ReadInt16(); |
|
796 TUint elemId; |
|
797 CCnvCharacterSetConverter::SCharacterSet elem; |
|
798 |
|
799 for (TInt i = 0; i < numCharacterSetElements; i++) |
|
800 { |
|
801 characterSetElementId = rscReader.ReadInt32(); |
|
802 for (TInt j = 0; j < iCharacterSet->Count(); j++ ) |
|
803 { |
|
804 elem = iCharacterSet->At(j); |
|
805 elemId = elem.Identifier(); |
|
806 if ( elemId == characterSetElementId && !IsInTopCharacterSet(characterSetElementId) ) |
|
807 { |
|
808 iTopCharacterSet->AppendL(elem); |
|
809 } |
|
810 } |
|
811 } |
|
812 |
|
813 CleanupStack::PopAndDestroy(rscBuf); |
|
814 } |
|
815 |
|
816 // ----------------------------------------------------------------------------- |
|
817 // CMPXPlaylistEngine::IsInTopCharacterSet() |
|
818 // ----------------------------------------------------------------------------- |
|
819 // |
|
820 TBool CMPXPlaylistEngine::IsInTopCharacterSet(TUint aCharacterSetId) |
|
821 { |
|
822 for (TInt i = 0; i < iTopCharacterSet->Count(); i++) |
|
823 { |
|
824 if ( iTopCharacterSet->At(i).Identifier() == aCharacterSetId ) |
|
825 { |
|
826 return ETrue; |
|
827 } |
|
828 } |
|
829 return EFalse; |
|
830 } |
|
831 |
|
832 // End of file |