mpx/playbackframework/playbackutility/src/mpxplaybackutilityimpl.cpp
changeset 0 a2952bb97e68
child 2 7a9a8e73f54b
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     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:  Playback Utility implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <bamdesca.h>
       
    20 #include <s32mem.h>
       
    21 #include <e32math.h>
       
    22 #include <mpxcmn.h>
       
    23 #include <mpxplaybackobserver.h>
       
    24 #include <mpxcollectionplaylist.h>
       
    25 #include <mpxmedia.h>
       
    26 #include <mpxmessagemonitor.h>
       
    27 #include <mpxtaskqueue.h>
       
    28 #include <mpxuser.h>
       
    29 #include <mpxmessagegeneraldefs.h>
       
    30 #include <mpxcommandgeneraldefs.h>
       
    31 #include <mpxcollectionpath.h>
       
    32 #include <mpxplaybackcommanddefs.h>
       
    33 #include <mpxsubscription.h>
       
    34 #include <mpxlog.h>
       
    35 
       
    36 #include "mpxplaybackserverdefs.h"
       
    37 #include "mpxplaybackutilityimpl.h"
       
    38 
       
    39 // ============================== MEMBER FUNCTIONS ============================
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // Retrieves playback utility from TLS. Creates if it's not there.
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 MMPXPlaybackUtility* CMPXPlaybackUtility::UtilityL(
       
    46     const TUid& aModeId,
       
    47     const TMPXCategory aCategory)
       
    48     {
       
    49     MPX_FUNC("CMPXPlaybackUtility::UtilityL");
       
    50     MMPXPlaybackUtility* utility( NULL );
       
    51     // Currently only make the default mode a singleton since it's used the most
       
    52     // If needed we could make other modes a singleton as well.  This is why
       
    53     // a struct was used to store in the TLS so that more utilities can be
       
    54     // added easily.
       
    55     if ( KPbModeDefault == aModeId )
       
    56         {
       
    57         TMPXPlaybackUtilityStruct* s( reinterpret_cast<TMPXPlaybackUtilityStruct*>( Dll::Tls() ));
       
    58         if ( !s )
       
    59             {
       
    60             MPX_DEBUG1("CMPXPlaybackUtility::UtilityL(): Creating default mode");
       
    61             utility = CMPXPlaybackUtility::NewL( aModeId, NULL, aCategory );
       
    62             CleanupClosePushL( *utility );
       
    63             MPX_DEBUG2("CMPXPlaybackUtility::UtilityL(): utility = 0x%08x", utility);
       
    64             s = new (ELeave) TMPXPlaybackUtilityStruct;
       
    65             s->iDefaultPlaybackUtility = utility;
       
    66             Dll::SetTls( s );
       
    67             CleanupStack::Pop( utility );
       
    68             }
       
    69         else
       
    70             {
       
    71             utility = s->iDefaultPlaybackUtility;
       
    72             MPX_DEBUG2("CMPXPlaybackUtility::UtilityL(): Retrieving default mode 0x%08x", utility);
       
    73             static_cast<CMPXPlaybackUtility*>( utility )->iRefCount++;
       
    74             }
       
    75         }
       
    76     else
       
    77         {
       
    78         MPX_DEBUG1("CMPXPlaybackUtility::UtilityL(): Not default mode");
       
    79         utility = CMPXPlaybackUtility::NewL( aModeId, NULL, aCategory );
       
    80         }
       
    81     return utility;
       
    82     }
       
    83 
       
    84 // ----------------------------------------------------------------------------
       
    85 // Two phases constructor
       
    86 // ----------------------------------------------------------------------------
       
    87 //
       
    88 CMPXPlaybackUtility* CMPXPlaybackUtility::NewL(const TUid& aModeId,
       
    89                                                MMPXPlaybackObserver* aObs,
       
    90                                                const TMPXCategory aCategory)
       
    91     {
       
    92     CMPXPlaybackUtility* p=new(ELeave)CMPXPlaybackUtility();
       
    93     CleanupStack::PushL(p);
       
    94     p->ConstructL(aModeId,aObs,aCategory);
       
    95     CleanupStack::Pop(p);
       
    96     return p;
       
    97     }
       
    98 
       
    99 // ----------------------------------------------------------------------------
       
   100 // Destructor
       
   101 // ----------------------------------------------------------------------------
       
   102 //
       
   103 CMPXPlaybackUtility::~CMPXPlaybackUtility()
       
   104     {
       
   105     MPX_FUNC_EX("CMPXPlaybackUtility::~CMPXPlaybackUtility");
       
   106     Cancel();
       
   107 #ifdef _ENABLE_GUARD_TIMER
       
   108     delete iGuardTimer;
       
   109 #endif
       
   110     if (iTaskQueue)
       
   111         {
       
   112         delete iTaskQueue;
       
   113         }
       
   114     if (iMsgMonitor)
       
   115         {
       
   116         delete iMsgMonitor;
       
   117         }
       
   118     iObservers.Close();
       
   119     iPbs.Close();
       
   120     iFile.Close();
       
   121     if (iBuffer)
       
   122         {
       
   123         delete iBuffer;
       
   124         }
       
   125     delete iMediaOnError;
       
   126 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
   127     iFile64.Close();
       
   128 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
   129     }
       
   130 
       
   131 // ----------------------------------------------------------------------------
       
   132 // C++ constructor
       
   133 // Create a unique name out of thread ID and this pointer: no other instance of
       
   134 // this object will have the same name; used to identify this object for
       
   135 // recieving messages
       
   136 // ----------------------------------------------------------------------------
       
   137 //
       
   138 CMPXPlaybackUtility::CMPXPlaybackUtility()
       
   139     : CActive(EPriorityStandard),
       
   140     iCallbackOngoing(EFalse)
       
   141     {
       
   142     CActiveScheduler::Add(this);
       
   143     }
       
   144 
       
   145 // ----------------------------------------------------------------------------
       
   146 // 2nd construtor
       
   147 // ----------------------------------------------------------------------------
       
   148 //
       
   149 void CMPXPlaybackUtility::ConstructL(const TUid& aModeId,
       
   150                                      MMPXPlaybackObserver* aObs, 
       
   151                                      const TMPXCategory aCategory)
       
   152     {
       
   153     MPX_FUNC_EX("CMPXPlaybackUtility::ConstructL()");
       
   154     MPX_DEBUG4("CMPXPlaybackUtility::ConstructL this 0x%08x mode 0x%08x observer 0x%08x",
       
   155                this, aModeId.iUid, aObs);
       
   156     if (aObs)
       
   157         {
       
   158         AddObserverL(*aObs);
       
   159         }
       
   160     iTaskQueue = CMPXTaskQueue::NewL();
       
   161     User::LeaveIfError(iPbs.Connect(KMPXPlaybackServerName,
       
   162                                     KMPXPlaybackServerImg,
       
   163                                     TVersion(KMPXPlaybackServerMajorVersionNumber,
       
   164                                              KMPXPlaybackServerMinorVersionNumber,
       
   165                                              KMPXPlaybackServerBuildVersionNumber)));
       
   166     iPbs.SendReceiveL(EPbsSetMode,TIpcArgs(aModeId.iUid, aCategory));
       
   167     iMsgMonitor = CMPXMessageMonitor::NewL(iPbs, *this);
       
   168 #ifdef _ENABLE_GUARD_TIMER
       
   169     iGuardTimer=CPeriodic::NewL(CActive::EPriorityStandard);
       
   170 #endif
       
   171     iMediaOnError = CMPXMedia::NewL();
       
   172     iRefCount++;
       
   173     }
       
   174 
       
   175 // ----------------------------------------------------------------------------
       
   176 // Add a observer
       
   177 // ----------------------------------------------------------------------------
       
   178 //
       
   179 void CMPXPlaybackUtility::AddObserverL(MMPXPlaybackObserver& aObs)
       
   180     {
       
   181     MPX_FUNC_EX("CMPXPlaybackUtility::AddObserverL()");
       
   182     iObservers.AppendL(&aObs);
       
   183     }
       
   184 
       
   185 // ----------------------------------------------------------------------------
       
   186 // Remove a observer
       
   187 // ----------------------------------------------------------------------------
       
   188 //
       
   189 void CMPXPlaybackUtility::RemoveObserverL(MMPXPlaybackObserver& aObs)
       
   190     {
       
   191     MPX_FUNC_EX("CMPXPlaybackUtility::RemoveObserverL()");
       
   192     TInt i=iObservers.FindL(&aObs);
       
   193     iObservers.Remove(i);
       
   194     }
       
   195 
       
   196 // ----------------------------------------------------------------------------
       
   197 // Returns PIds of clients that are using the engine in the mode
       
   198 // ----------------------------------------------------------------------------
       
   199 //
       
   200 void CMPXPlaybackUtility::GetClientsL(RArray<TProcessId>& aClients)
       
   201     {
       
   202     MPX_FUNC_EX("CMPXPlaybackUtility::GetClientsL()");
       
   203     TInt size = iPbs.SendReceiveL(EPbsGetClients);
       
   204     ::ArrayFromServerL<TProcessId>(iPbs, EPbsGetSyncBuffer,size,aClients);
       
   205     }
       
   206 
       
   207 // ----------------------------------------------------------------------------
       
   208 // Initializes a track given by aIndex in path aCollectionPath
       
   209 // ----------------------------------------------------------------------------
       
   210 //
       
   211 void CMPXPlaybackUtility::InitL(
       
   212     const CMPXCollectionPlaylist& aPlaylist,
       
   213     TBool aPlay /*=ETrue*/ )
       
   214     {
       
   215     MPX_FUNC("CMPXPlaybackUtility::InitL()");
       
   216     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitL()");
       
   217     CBufBase* buffer(NULL);
       
   218     ::CreateBufferL<CMPXCollectionPlaylist>(aPlaylist, buffer);
       
   219     CleanupStack::PushL( buffer );
       
   220     TPtr8 p=buffer->Ptr(0);
       
   221     iPbs.SendReceiveL(EPbsInitFromCollection,TIpcArgs(&p,aPlay));
       
   222     CleanupStack::PopAndDestroy( buffer );
       
   223     }
       
   224 
       
   225 // ----------------------------------------------------------------------------
       
   226 // Inititialises with a single song, may not be part of any collection
       
   227 // ----------------------------------------------------------------------------
       
   228 //
       
   229 void CMPXPlaybackUtility::InitL(const TDesC& aUri,const TDesC8* aType)
       
   230     {
       
   231     MPX_FUNC("CMPXPlaybackUtility::InitL(const TDesC& aUri,const TDesC8* aType)");
       
   232     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitL()");
       
   233     const TDesC8& type=aType?*aType:KNullDesC8;
       
   234     TPtrC8 uri = MPXUser::Ptr(aUri);
       
   235     iPbs.SendReceiveL(EPbsInitFromUri,TIpcArgs(&uri,&type));
       
   236     }
       
   237 
       
   238 // ----------------------------------------------------------------------------
       
   239 // Inititialises with a single song, may not be part of any collection
       
   240 // ----------------------------------------------------------------------------
       
   241 //
       
   242 void CMPXPlaybackUtility::InitL(RFile& aShareableFile)
       
   243     {
       
   244     MPX_FUNC("CMPXPlaybackUtility::InitL(RFile& aShareableFile)");
       
   245     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitL()");
       
   246     if (!aShareableFile.SubSessionHandle())
       
   247         {
       
   248         User::Leave(KErrArgument);
       
   249         }
       
   250     TIpcArgs args;
       
   251     aShareableFile.TransferToServer(args,0,1);
       
   252     iPbs.SendReceiveL(EPbsInitFromFile,args);
       
   253     }
       
   254 
       
   255 // ----------------------------------------------------------------------------
       
   256 // Inititialises with a URI
       
   257 // ----------------------------------------------------------------------------
       
   258 //
       
   259 void CMPXPlaybackUtility::InitStreamingL(const TDesC& aUri, const TDesC8* aType, const TInt aAccessPoint)
       
   260 {
       
   261     MPX_FUNC("CMPXPlaybackUtility::InitStreamingL(const TDesC& aUri, const TInt aAccessPoint)");
       
   262     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitStreamingL()");
       
   263 
       
   264     const TDesC8& type=aType?*aType:KNullDesC8;
       
   265     TPtrC8 uri = MPXUser::Ptr(aUri);
       
   266     iPbs.SendReceiveL(EPbsInitStreamingFromUri,TIpcArgs(&uri, &type, aAccessPoint));
       
   267 
       
   268 }
       
   269 
       
   270 
       
   271 // ----------------------------------------------------------------------------
       
   272 // Inititialises with a file, may not be part of any collection
       
   273 // ----------------------------------------------------------------------------
       
   274 //
       
   275 void CMPXPlaybackUtility::InitStreamingL(RFile& aShareableFile, const TInt aAccessPoint)
       
   276 {
       
   277     MPX_FUNC("CMPXPlaybackUtility::InitStreamingL(RFile& aShareableFile, const TInt aAccessPoint)");
       
   278     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitStreamingL()");
       
   279     if (!aShareableFile.SubSessionHandle())
       
   280         {
       
   281         User::Leave(KErrArgument);
       
   282         }
       
   283     TIpcArgs args;
       
   284     aShareableFile.TransferToServer(args,0,1); 
       
   285     args.Set(2, aAccessPoint);  //use index "2" for setting the AccessPoint   
       
   286 
       
   287     iPbs.SendReceiveL(EPbsInitStreamingFromFile, args);
       
   288 }
       
   289 
       
   290 // ----------------------------------------------------------------------------
       
   291 // Frees up client side resources only; a player is freed when there are no
       
   292 // clients using it, and all resources are freed when the last client closed
       
   293 // ----------------------------------------------------------------------------
       
   294 //
       
   295 void CMPXPlaybackUtility::Close()
       
   296     {
       
   297     MPX_DEBUG2("CMPXPlaybackUtility::Close 0x%08x", this);
       
   298     ASSERT( iRefCount > 0 );
       
   299     if ( --iRefCount == 0 )
       
   300         {
       
   301         // last client released
       
   302         iMsgMonitor->Cancel();
       
   303         TMPXPlaybackUtilityStruct* s( reinterpret_cast<TMPXPlaybackUtilityStruct*>( Dll::Tls() ));
       
   304         if ( s )
       
   305             {
       
   306             if ( s->iDefaultPlaybackUtility == this )
       
   307                 {
       
   308                 delete s;
       
   309                 Dll::SetTls( NULL );
       
   310                 }
       
   311             }
       
   312         delete this;
       
   313         }
       
   314     }
       
   315 
       
   316 // ----------------------------------------------------------------------------
       
   317 // Stops any async operations that are currently under way
       
   318 // ----------------------------------------------------------------------------
       
   319 //
       
   320 void CMPXPlaybackUtility::CancelRequest()
       
   321     {
       
   322     MPX_FUNC_EX("CMPXPlaybackUtility::CancelRequest()");
       
   323     Cancel();
       
   324     iTaskQueue->Reset();
       
   325     }
       
   326 
       
   327 // ----------------------------------------------------------------------------
       
   328 // Issue player commands, with optional data.
       
   329 // ----------------------------------------------------------------------------
       
   330 //
       
   331 void CMPXPlaybackUtility::CommandL(TMPXPlaybackCommand aCmd,TInt aData)
       
   332     {
       
   333     MPX_DEBUG2("-->CMPXPlaybackUtility::CommandL(%d)", aCmd);
       
   334     MPX_DEBUG_THREAD("CMPXPlaybackUtility::CommandL()");
       
   335     CMPXCommand* cmd = CMPXCommand::NewL();
       
   336     CleanupStack::PushL(cmd);
       
   337     cmd->SetTObjectValueL<TInt>(KMPXCommandGeneralId, KMPXCommandIdPlaybackGeneral);
       
   338     // All of current commands are sync
       
   339     cmd->SetTObjectValueL<TBool>(KMPXCommandGeneralDoSync, ETrue);
       
   340     cmd->SetTObjectValueL<TInt>(KMPXCommandPlaybackGeneralType, aCmd);
       
   341     cmd->SetTObjectValueL<TInt>(KMPXCommandPlaybackGeneralData, aData);
       
   342     CommandL(*cmd, NULL);
       
   343     CleanupStack::PopAndDestroy(cmd);
       
   344     MPX_DEBUG2("<--CMPXPlaybackUtility::CommandL(%d)", aCmd);
       
   345     }
       
   346 
       
   347 // ----------------------------------------------------------------------------
       
   348 // Issue player commands
       
   349 // ----------------------------------------------------------------------------
       
   350 //
       
   351 void CMPXPlaybackUtility::CommandL(
       
   352     CMPXCommand& aCmd,
       
   353     MMPXPlaybackCallback* aCallback/*=NULL*/)
       
   354     {
       
   355     MPX_FUNC_EX("CMPXPlaybackUtility::CommandL(CMPXCommand& aCmd)");
       
   356     MPX_DEBUG_THREAD("CMPXPlaybackUtility::CommandL(CMPXCommand& aCmd)");
       
   357     ASSERT(aCmd.IsSupported(KMPXCommandGeneralId));
       
   358     TInt id = aCmd.ValueTObjectL<TInt>(KMPXCommandGeneralId);
       
   359     MPX_DEBUG2("CMPXPlaybackUtility::CommandL(): id = 0x%08x", id);
       
   360     if (KMPXCommandIdPlaybackGeneral==id)
       
   361         {
       
   362         ASSERT(aCmd.IsSupported(KMPXCommandPlaybackGeneralType));
       
   363         TMPXPlaybackCommand cmdType = static_cast<TMPXPlaybackCommand>(
       
   364                       aCmd.ValueTObjectL<TInt>(KMPXCommandPlaybackGeneralType));
       
   365         MPX_DEBUG2("CMPXPlaybackUtility::CommandL(): cmdType = %d", cmdType);
       
   366         if ( EPbCmdPlay == cmdType ||
       
   367              EPbCmdPlayPause == cmdType ||
       
   368              EPbCmdStop == cmdType)
       
   369             {
       
   370             aCmd.SetTObjectValueL<TProcessId>(KMPXCommandPlaybackGeneralClientPid,
       
   371                                               RProcess().Id()); // current process id
       
   372             }
       
   373         }
       
   374 
       
   375     TBool asyncVar(ETrue); // by default command is asynchronous
       
   376     if (aCmd.IsSupported(KMPXCommandGeneralDoSync))
       
   377         { // check if command is sync
       
   378         asyncVar=!(aCmd.ValueTObjectL<TBool>(KMPXCommandGeneralDoSync));
       
   379         }
       
   380     CBufBase* buf(NULL);
       
   381     ::CreateBufferL<CMPXCommand>( aCmd, buf );
       
   382     CleanupStack::PushL( buf );
       
   383     TPtr8 ptr = buf->Ptr(0);
       
   384     if (asyncVar)
       
   385         { // async request
       
   386         ASSERT(aCallback); // callback must be provided for asynchronous command
       
   387         // Increase reference count on command ownership transferred
       
   388         CMPXCommand* ref = CMPXCommand::NewL(aCmd);
       
   389         // Async version, Add request to the task queue
       
   390         CleanupStack::PushL(ref);
       
   391         AddRequestL(EPbsCommand, aCallback, asyncVar, buf, NULL, ref );
       
   392         CleanupStack::Pop(ref);
       
   393         CleanupStack::Pop( buf );  // ownership transferred to the queue
       
   394         }
       
   395     else
       
   396         { // send request if sync
       
   397         iPbs.SendReceiveL(EPbsCommand, TIpcArgs(asyncVar, &ptr));
       
   398         CleanupStack::PopAndDestroy( buf );
       
   399         }
       
   400     }
       
   401 
       
   402 // ----------------------------------------------------------------------------
       
   403 // Current state of player
       
   404 // ----------------------------------------------------------------------------
       
   405 //
       
   406 TMPXPlaybackState CMPXPlaybackUtility::StateL() const
       
   407     {
       
   408     MPX_DEBUG2("CMPXPlaybackUtility::StateL 0x%08x", this);
       
   409     return static_cast<TMPXPlaybackState>(iPbs.SendReceiveL(EPbsGetState));
       
   410     }
       
   411 
       
   412 // ----------------------------------------------------------------------------
       
   413 // Determine whether there is a song by the state of the engine: if there is,
       
   414 // its OK to return MMPXMedia, else NULL is returned
       
   415 // ----------------------------------------------------------------------------
       
   416 //
       
   417 MMPXSource* CMPXPlaybackUtility::Source()
       
   418     {
       
   419     MPX_FUNC_EX("CMPXPlaybackUtility::Source()");
       
   420     TMPXPlaybackState s=EPbStateNotInitialised;
       
   421     TRAP_IGNORE(s=StateL());
       
   422     return (s==EPbStateNotInitialised ||
       
   423             s==EPbStateShuttingDown) ? NULL:this;
       
   424     }
       
   425 
       
   426 // ----------------------------------------------------------------------------
       
   427 // Get player manager
       
   428 // ----------------------------------------------------------------------------
       
   429 //
       
   430 MMPXPlayerManager& CMPXPlaybackUtility::PlayerManager()
       
   431     {
       
   432     return *this;
       
   433     }
       
   434 
       
   435 // ----------------------------------------------------------------------------
       
   436 // Set playback property, EPropertyChanged event when complete
       
   437 // ----------------------------------------------------------------------------
       
   438 //
       
   439 void CMPXPlaybackUtility::SetL(TMPXPlaybackProperty aProperty,TInt aValue)
       
   440     {
       
   441     MPX_FUNC_EX("CMPXPlaybackUtility::SetL()");
       
   442     iPbs.SendReceiveL(EPbsSetProperty,TIpcArgs(aProperty,aValue));
       
   443     }
       
   444 
       
   445 // ----------------------------------------------------------------------------
       
   446 // Send property request
       
   447 // Result will be called back in HandleProperty
       
   448 // ----------------------------------------------------------------------------
       
   449 //
       
   450 void CMPXPlaybackUtility::ValueL(MMPXPlaybackCallback& aCallback,
       
   451                                  TMPXPlaybackProperty aProperty)
       
   452     {
       
   453     MPX_FUNC_EX("CMPXPlaybackUtility::ValueL()");
       
   454     PropertyL(aCallback, aProperty);
       
   455     }
       
   456 
       
   457 // ----------------------------------------------------------------------------
       
   458 // Send property request
       
   459 // Result will be called back in HandleProperty
       
   460 // ----------------------------------------------------------------------------
       
   461 //
       
   462 void CMPXPlaybackUtility::PropertyL(
       
   463     MMPXPlaybackCallback& aCallback,
       
   464     TMPXPlaybackProperty aProperty)
       
   465     {
       
   466     MPX_DEBUG2("-->CMPXPlaybackUtility::PropertyL(%d)", aProperty);
       
   467     MPX_DEBUG_THREAD("CMPXPlaybackUtility::PropertyL()");
       
   468     AddRequestL(EPbsGetProperty, &aCallback, aProperty);
       
   469     MPX_DEBUG2("<--CMPXPlaybackUtility::PropertyL(%d)", aProperty);
       
   470     }
       
   471 
       
   472 // ----------------------------------------------------------------------------
       
   473 // Return a list of mime types supported by playback framework
       
   474 // ----------------------------------------------------------------------------
       
   475 //
       
   476 CDesCArray* CMPXPlaybackUtility::SupportedMimeTypes()
       
   477     {
       
   478     MPX_FUNC_EX("CMPXPlaybackUtility::SupportedMimeTypes()");
       
   479     TInt size = 0;
       
   480     TRAPD( err, size = iPbs.SendReceiveL( EPbsGetSupportedMimeTypes ) );
       
   481     CDesCArray* desArray = NULL;
       
   482     if ( size && ( err == KErrNone ) )
       
   483         {
       
   484         TRAP_IGNORE(
       
   485         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, size, iBuffer);
       
   486         MPXUser::CreateFromBufferL(*iBuffer, desArray));
       
   487         }
       
   488     return desArray;
       
   489     }
       
   490 
       
   491 // ----------------------------------------------------------------------------
       
   492 // Return a list of mime types supported by playback framework
       
   493 // ----------------------------------------------------------------------------
       
   494 //
       
   495 CDesCArray* CMPXPlaybackUtility::SupportedExtensions()
       
   496     {
       
   497     MPX_FUNC_EX("CMPXPlaybackUtility::SupportedExtensions()");
       
   498     TInt size = 0;
       
   499     TRAPD( err, size = iPbs.SendReceiveL( EPbsGetSupportedExtensions ) );
       
   500     CDesCArray* desArray = NULL;
       
   501     if ( size && ( err == KErrNone ) )
       
   502         {
       
   503         TRAP_IGNORE(
       
   504         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, size, iBuffer);
       
   505         MPXUser::CreateFromBufferL(*iBuffer, desArray));
       
   506         }
       
   507     return desArray;
       
   508     }
       
   509 
       
   510 // ----------------------------------------------------------------------------
       
   511 // Return a list of mime types supported by playback framework
       
   512 // ----------------------------------------------------------------------------
       
   513 //
       
   514 CDesCArray* CMPXPlaybackUtility::SupportedSchemas()
       
   515     {
       
   516     MPX_FUNC_EX("CMPXPlaybackUtility::SupportedSchemas()");
       
   517     TInt size = 0;
       
   518     TRAPD( err, size = iPbs.SendReceiveL( EPbsGetSupportedSchemas ) );
       
   519     CDesCArray* desArray = NULL;
       
   520     if ( size && ( err == KErrNone ) )
       
   521         {
       
   522         TRAP_IGNORE(
       
   523         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, size, iBuffer);
       
   524         MPXUser::CreateFromBufferL(*iBuffer, desArray));
       
   525         }
       
   526     return desArray;
       
   527     }
       
   528 
       
   529 // ----------------------------------------------------------------------------
       
   530 // Sets the priority of the playback utility
       
   531 // ----------------------------------------------------------------------------
       
   532 //
       
   533 void CMPXPlaybackUtility::SetPriority( TInt aPriority )
       
   534     {
       
   535     MPX_DEBUG2("-->CMPXPlaybackUtility::SetPriority(%d)", aPriority);
       
   536     MPX_DEBUG_THREAD("CMPXPlaybackUtility::SetPriority()");
       
   537     CActive::SetPriority( aPriority );
       
   538     MPX_DEBUG2("-->CMPXPlaybackUtility::SetPriority(%d)", aPriority);
       
   539     }
       
   540 
       
   541 
       
   542 // ----------------------------------------------------------------------------
       
   543 // CMPXPlaybackUtility::AddSubscriptionL
       
   544 // ----------------------------------------------------------------------------
       
   545 //
       
   546 void CMPXPlaybackUtility::AddSubscriptionL(
       
   547     const CMPXSubscription& aSubscription)
       
   548     {
       
   549     const CMPXMediaArray* items = aSubscription.ItemsL();
       
   550     User::LeaveIfNull(const_cast<CMPXMediaArray*>(items));
       
   551     CMPXCommand* cmd = CMPXCommand::NewL();
       
   552     CleanupStack::PushL(cmd);
       
   553     cmd->SetTObjectValueL(KMPXCommandGeneralId, KMPXCommandSubscriptionAdd);
       
   554     cmd->SetCObjectValueL(KMPXCommandSubscriptionAddItems, items);
       
   555     cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue);
       
   556     CommandL(*cmd);
       
   557     CleanupStack::PopAndDestroy(cmd);
       
   558     }
       
   559 
       
   560 // ----------------------------------------------------------------------------
       
   561 // CMPXPlaybackUtility::RemoveSubscriptionL
       
   562 // ----------------------------------------------------------------------------
       
   563 //
       
   564 void CMPXPlaybackUtility::RemoveSubscriptionL(
       
   565     const CMPXSubscription& aSubscription)
       
   566     {
       
   567     const CMPXMediaArray* items = aSubscription.ItemsL();
       
   568     User::LeaveIfNull(const_cast<CMPXMediaArray*>(items));
       
   569     CMPXCommand* cmd = CMPXCommand::NewL();
       
   570     CleanupStack::PushL(cmd);
       
   571     cmd->SetTObjectValueL(KMPXCommandGeneralId, KMPXCommandSubscriptionRemove);
       
   572     cmd->SetCObjectValueL(KMPXCommandSubscriptionAddItems, items);
       
   573     cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue);
       
   574     CommandL(*cmd);
       
   575     CleanupStack::PopAndDestroy(cmd);
       
   576     }
       
   577 
       
   578 // ----------------------------------------------------------------------------
       
   579 // CMPXPlaybackUtility::ClearSubscriptionsL
       
   580 // ----------------------------------------------------------------------------
       
   581 //
       
   582 void CMPXPlaybackUtility::ClearSubscriptionsL()
       
   583     {
       
   584     CMPXCommand* cmd = CMPXCommand::NewL();
       
   585     CleanupStack::PushL(cmd);
       
   586     cmd->SetTObjectValueL(KMPXCommandGeneralId, KMPXCommandSubscriptionRemoveAll);
       
   587     cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue);
       
   588     CommandL(*cmd);
       
   589     CleanupStack::PopAndDestroy(cmd);
       
   590     }
       
   591 // ----------------------------------------------------------------------------
       
   592 // Get a list of player types
       
   593 // ----------------------------------------------------------------------------
       
   594 //
       
   595 void CMPXPlaybackUtility::GetPlayerTypesL(
       
   596     RArray<TMPXPlaybackPlayerType>& aTypes)
       
   597     {
       
   598     MPX_FUNC_EX("CMPXPlaybackUtility::GetPlayerTypesL()");
       
   599     TInt size = iPbs.SendReceiveL(EPbsGetPlayerTypes);
       
   600     ::ArrayFromServerL<TMPXPlaybackPlayerType>(iPbs, EPbsGetSyncBuffer,size,aTypes);
       
   601     }
       
   602 
       
   603 // ----------------------------------------------------------------------------
       
   604 // Returns display name for custom types
       
   605 // ----------------------------------------------------------------------------
       
   606 //
       
   607 HBufC* CMPXPlaybackUtility::PlayerTypeDisplayNameL(TMPXPlaybackPlayerType aType)
       
   608     {
       
   609     MPX_FUNC_EX("CMPXPlaybackUtility::PlayerTypeDisplayNameL()");
       
   610     return DesL(iPbs.SendReceiveL(EPbsGetPlayerTypeDisplayName,TIpcArgs(aType)));
       
   611     }
       
   612 
       
   613 // ----------------------------------------------------------------------------
       
   614 // Get the list of UIDs of all players
       
   615 // ----------------------------------------------------------------------------
       
   616 //
       
   617 void CMPXPlaybackUtility::GetPlayerListL(RArray<TUid>& aPlayers)
       
   618     {
       
   619     MPX_FUNC_EX("CMPXPlaybackUtility::GetPlayerListL(Rarray)");
       
   620     TInt size = iPbs.SendReceiveL(EPbsGetAllPlayersUids);
       
   621     ::ArrayFromServerL<TUid>(iPbs, EPbsGetSyncBuffer,size,aPlayers);
       
   622     }
       
   623 
       
   624 // ----------------------------------------------------------------------------
       
   625 // Get the list of UIDs of players with the specific type
       
   626 // ----------------------------------------------------------------------------
       
   627 //
       
   628 void CMPXPlaybackUtility::GetPlayerListL(RArray<TUid>& aPlayers,
       
   629                                          TMPXPlaybackPlayerType aType)
       
   630     {
       
   631     MPX_FUNC_EX("CMPXPlaybackUtility::GetPlayerListL(TMPXPlaybackPlayerType)");
       
   632     TInt size = iPbs.SendReceiveL(EPbsGetPlayersUidsForType, TIpcArgs(aType));
       
   633     ::ArrayFromServerL<TUid>(iPbs, EPbsGetSyncBuffer,size,aPlayers);
       
   634     }
       
   635 
       
   636 // ----------------------------------------------------------------------------
       
   637 // Asynchronous method: when server completes message, RunL() will be called
       
   638 // and then the observer is notified of the results. Data required for the
       
   639 // results that is not supplied by the server is stored; data supplied by the
       
   640 // server is written back into packaged descriptors in this address space
       
   641 // ----------------------------------------------------------------------------
       
   642 //
       
   643 void CMPXPlaybackUtility::SubPlayerNamesL(MMPXPlaybackCallback& aCallback,
       
   644                                           TUid aPlayer)
       
   645     {
       
   646     MPX_FUNC_EX("CMPXPlaybackUtility::SubPlayerNamesL()");
       
   647     AddRequestL(EPbsGetSubPlayerNamesByUid, &aCallback, aPlayer.iUid);
       
   648     }
       
   649 
       
   650 // ----------------------------------------------------------------------------
       
   651 // Selects all players with the type
       
   652 // ----------------------------------------------------------------------------
       
   653 //
       
   654 void CMPXPlaybackUtility::SelectPlayersL(TMPXPlaybackPlayerType aType)
       
   655     {
       
   656     MPX_FUNC_EX("CMPXPlaybackUtility::SelectPlayersL(TMPXPlaybackPlayerType)");
       
   657     iPbs.SendReceiveL(EPbsSelectPlayerByType,TIpcArgs(aType));
       
   658     }
       
   659 
       
   660 // ----------------------------------------------------------------------------
       
   661 // Selects a specific player
       
   662 // ----------------------------------------------------------------------------
       
   663 //
       
   664 void CMPXPlaybackUtility::SelectPlayerL(TUid aPlayer)
       
   665     {
       
   666     MPX_FUNC_EX("CMPXPlaybackUtility::SelectPlayersL(TUid)");
       
   667     iPbs.SendReceiveL(EPbsSelectPlayerByUid,TIpcArgs(aPlayer.iUid));
       
   668     }
       
   669 
       
   670 // ----------------------------------------------------------------------------
       
   671 // Selects a specific player and sub player
       
   672 // ----------------------------------------------------------------------------
       
   673 //
       
   674 void CMPXPlaybackUtility::SelectSubPlayerL(TUid aPlayer,TInt aSubPlayerIndex)
       
   675     {
       
   676     MPX_FUNC_EX("CMPXPlaybackUtility::SelectSubPlayerL()");
       
   677     iPbs.SendReceiveL(EPbsSelectSubPlayer,
       
   678                       TIpcArgs(aPlayer.iUid,aSubPlayerIndex));
       
   679     }
       
   680 
       
   681 // ----------------------------------------------------------------------------
       
   682 // Clears all selection criteria.
       
   683 // ----------------------------------------------------------------------------
       
   684 //
       
   685 void CMPXPlaybackUtility::ClearSelectPlayersL()
       
   686     {
       
   687     MPX_FUNC_EX("CMPXPlaybackUtility::ClearSelectPlayersL()");
       
   688     iPbs.SendReceiveL(EPbsClearPlayerSelection);
       
   689     }
       
   690 
       
   691 // ----------------------------------------------------------------------------
       
   692 // Retreives the current selection
       
   693 // ----------------------------------------------------------------------------
       
   694 //
       
   695 void CMPXPlaybackUtility::GetSelectionL(TMPXPlaybackPlayerType& aType,
       
   696                                         TUid& aPlayer,
       
   697                                         TInt& aSubPlayerIndex,
       
   698                                         HBufC*& aSubPlayerName)
       
   699     {
       
   700     MPX_FUNC_EX("CMPXPlaybackUtility::GetSelectionL()");
       
   701     if (aSubPlayerName)
       
   702         {
       
   703         delete aSubPlayerName;
       
   704         aSubPlayerName = NULL;
       
   705         }
       
   706     TPckg<TMPXPlaybackPlayerType> type(aType);
       
   707     TPckg<TUid> uid(aPlayer);
       
   708     TPckg<TInt> index(aSubPlayerIndex);
       
   709     TPckgBuf<TInt> size;
       
   710     iPbs.SendReceiveL(EPbsGetSelection,TIpcArgs(&type,&uid,&index, &size));
       
   711     if (size())
       
   712         {
       
   713         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, size(), iBuffer);
       
   714         aSubPlayerName = MPXUser::Ptr(iBuffer->Ptr(0)).AllocL();
       
   715         } // else aSubPlayer return NULL;
       
   716     }
       
   717 
       
   718 // ----------------------------------------------------------------------------
       
   719 // The current player
       
   720 // ----------------------------------------------------------------------------
       
   721 //
       
   722 MMPXPlayer* CMPXPlaybackUtility::CurrentPlayer()
       
   723     {
       
   724     MPX_FUNC_EX("CMPXPlaybackUtility::CurrentPlayer()");
       
   725     TInt r=0;
       
   726     TRAP_IGNORE(r=iPbs.SendReceiveL(EPbsPlayerFound));
       
   727     return r ? this : NULL;
       
   728     }
       
   729 
       
   730 // ----------------------------------------------------------------------------
       
   731 // The 'type' of the player
       
   732 // ----------------------------------------------------------------------------
       
   733 //
       
   734 TMPXPlaybackPlayerType CMPXPlaybackUtility::TypeL()
       
   735     {
       
   736     MPX_FUNC_EX("CMPXPlaybackUtility::TypeL()");
       
   737     return static_cast<TMPXPlaybackPlayerType>(
       
   738                                 iPbs.SendReceiveL(EPbsGetPlayerType));
       
   739     }
       
   740 
       
   741 // ----------------------------------------------------------------------------
       
   742 // The name of player type
       
   743 // ----------------------------------------------------------------------------
       
   744 //
       
   745 HBufC* CMPXPlaybackUtility::TypeNameL()
       
   746     {
       
   747     MPX_FUNC_EX("CMPXPlaybackUtility::TypeNameL()");
       
   748     return DesL(iPbs.SendReceiveL(EPbsGetTypeName));
       
   749     }
       
   750 
       
   751 // ----------------------------------------------------------------------------
       
   752 // Get sub players
       
   753 // ----------------------------------------------------------------------------
       
   754 //
       
   755 void CMPXPlaybackUtility::SubPlayerNamesL(MMPXPlaybackCallback& aCallback)
       
   756     {
       
   757     MPX_FUNC_EX("CMPXPlaybackUtility::SubPlayerNamesL()");
       
   758     SubPlayerNamesL(aCallback,UidL());
       
   759     }
       
   760 
       
   761 // ----------------------------------------------------------------------------
       
   762 // Selected sub player index
       
   763 // ----------------------------------------------------------------------------
       
   764 //
       
   765 TInt CMPXPlaybackUtility::SubPlayerL() const
       
   766     {
       
   767     MPX_DEBUG2("CMPXPlaybackUtility::SubPlayerL 0x%08x", this);
       
   768     return iPbs.SendReceiveL(EPbsGetSubPlayerIndex);
       
   769     }
       
   770 
       
   771 // ----------------------------------------------------------------------------
       
   772 // The UID identifying this player
       
   773 // ----------------------------------------------------------------------------
       
   774 //
       
   775 TUid CMPXPlaybackUtility::UidL() const
       
   776     {
       
   777     MPX_DEBUG2("-->CMPXPlaybackUtility::UidL 0x%08x", this);
       
   778     TPckgBuf<TInt> uidPkg;
       
   779     iPbs.SendReceiveL(EPbsGetPlayerUid, TIpcArgs(&uidPkg));
       
   780     MPX_DEBUG2("<--CMPXPlaybackUtility::UidL 0x%08x", this);
       
   781     return TUid::Uid(uidPkg());
       
   782     }
       
   783 
       
   784 // ----------------------------------------------------------------------------
       
   785 // Path to the collection
       
   786 // ----------------------------------------------------------------------------
       
   787 //
       
   788 CMPXCollectionPlaylist* CMPXPlaybackUtility::PlaylistL()
       
   789     {
       
   790     MPX_FUNC_EX("CMPXPlaybackUtility::PlaylistL()");
       
   791     CMPXCollectionPlaylist *p = NULL;
       
   792     TInt size = iPbs.SendReceiveL(EPbsGetCollectionPlaylist);
       
   793     if (size > 0)
       
   794         {
       
   795         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, size, iBuffer);
       
   796         ::NewFromBufferL<CMPXCollectionPlaylist>(*iBuffer, p);
       
   797         }
       
   798     return p;
       
   799     }
       
   800 
       
   801 // ----------------------------------------------------------------------------
       
   802 // Return file handle
       
   803 // ----------------------------------------------------------------------------
       
   804 //
       
   805 RFile* CMPXPlaybackUtility::FileL()
       
   806     {
       
   807     MPX_FUNC_EX("CMPXPlaybackUtility::FileL()");
       
   808     TPckgBuf<TInt> fileHandle;
       
   809     TInt fsHandle = iPbs.SendReceiveL(EPbsGetFile,TIpcArgs(&fileHandle));
       
   810     RFile* file(NULL);
       
   811     if (KErrNotFound != fileHandle())
       
   812         {
       
   813         iFile.Close();
       
   814         User::LeaveIfError(iFile.AdoptFromServer(fsHandle,fileHandle()));
       
   815         file = &iFile;
       
   816         } // else return NULL
       
   817     return file;
       
   818     }
       
   819 
       
   820 // ----------------------------------------------------------------------------
       
   821 // URI of current song
       
   822 // ----------------------------------------------------------------------------
       
   823 //
       
   824 HBufC* CMPXPlaybackUtility::UriL()
       
   825     {
       
   826     MPX_FUNC_EX("CMPXPlaybackUtility::UriL()");
       
   827     return DesL(iPbs.SendReceiveL(EPbsGetUri));
       
   828     }
       
   829 
       
   830 // ----------------------------------------------------------------------------
       
   831 // Request for media properties.
       
   832 // ----------------------------------------------------------------------------
       
   833 //
       
   834 void CMPXPlaybackUtility::MediaL(
       
   835     const TArray<TMPXAttribute>& aAttrs,
       
   836     MMPXPlaybackCallback& aCallback)
       
   837     {
       
   838     MPX_FUNC_EX( "-->CMPXPlaybackUtility::MediaL 2 parameters" );
       
   839     MediaL( aAttrs, aCallback, NULL );
       
   840     }
       
   841 
       
   842 // ----------------------------------------------------------------------------
       
   843 // Request for media properties.
       
   844 // ----------------------------------------------------------------------------
       
   845 //
       
   846 void CMPXPlaybackUtility::MediaL(
       
   847     const TArray<TMPXAttribute>& aAttrs,
       
   848     MMPXPlaybackCallback& aCallback,
       
   849     CMPXAttributeSpecs* aSpecs)
       
   850     {
       
   851     MPX_FUNC_EX( "-->CMPXPlaybackUtility::MediaL 3 parameters" );
       
   852     MPX_DEBUG_THREAD("CMPXPlaybackUtility::MediaL()");
       
   853 
       
   854     CMPXCommand* cmd = CMPXCommand::NewL();
       
   855     CleanupStack::PushL( cmd );
       
   856     cmd->SetTObjectValueL<TInt>(KMPXCommandGeneralId, KMPXCommandContentIdMedia);
       
   857 
       
   858     CBufBase* buf = CBufFlat::NewL( KMPXBufGranularity );
       
   859     CleanupStack::PushL( buf );
       
   860     RBufWriteStream writeStream( *buf );
       
   861     CleanupClosePushL( writeStream );
       
   862     // externalize attributes array
       
   863     ::ExternalizeL(aAttrs, writeStream);
       
   864     // Close and compress buffer
       
   865     writeStream.CommitL();
       
   866     buf->Compress();
       
   867     CleanupStack::PopAndDestroy( &writeStream );
       
   868     TPtrC ptr = MPXUser::Ptr( buf->Ptr( 0 ) );
       
   869     cmd->SetTextValueL( KMPXCommandMediaAttribute, ptr );
       
   870     CleanupStack::PopAndDestroy( buf );
       
   871 
       
   872     CMPXAttributeSpecs* attrSpecs = aSpecs ?
       
   873             CMPXAttributeSpecs::NewL(*aSpecs) : CMPXAttributeSpecs::NewL();
       
   874     CleanupStack::PushL(attrSpecs);
       
   875     cmd->SetCObjectValueL<CMPXAttributeSpecs>(
       
   876         KMPXCommandMediaAttributeSpecs, attrSpecs );
       
   877     CleanupStack::PopAndDestroy(attrSpecs);
       
   878 
       
   879     AddRequestL(EPbsGetMedia, &aCallback, 0, NULL, (TAny*)cmd, cmd );
       
   880     CleanupStack::Pop( cmd ); // Ownership transferred to the task queue
       
   881     }
       
   882 
       
   883 // ----------------------------------------------------------------------------
       
   884 // Server has completed the message, and if there's no error, the results are
       
   885 // available. The server completes with the function id (or error) so the correct
       
   886 // callback is made
       
   887 // ----------------------------------------------------------------------------
       
   888 //
       
   889 void CMPXPlaybackUtility::RunL()
       
   890     {
       
   891 #ifdef _ENABLE_GUARD_TIMER
       
   892     iGuardTimer->Cancel();
       
   893 #endif
       
   894     TInt err=iStatus.Int();
       
   895     TInt task = iTaskQueue->Task();
       
   896     MPX_DEBUG4("CMPXPlaybackUtility::RunL 0x%08x task %d err%d",
       
   897             this, task, err);
       
   898     if (KErrNotFound == task)
       
   899         {
       
   900         return;
       
   901         }
       
   902     
       
   903     // Try again in case server is down for IAD
       
   904     if (err == KErrDied || err == KErrServerTerminated)
       
   905         {
       
   906         MPX_DEBUG3("-->CMPXPlaybackUtility::RunL Reconnecting session for IAD 0x%08x task %d",
       
   907                 this, task);
       
   908         
       
   909         // attempt to bring the server back up
       
   910         err = iPbs.Reconnect();
       
   911         
       
   912         if (err != KErrNone)
       
   913             {
       
   914             MPX_DEBUG1("-->CMPXPlaybackUtility::RunL Reconnect Failed");
       
   915             }
       
   916         }
       
   917         
       
   918     User::LeaveIfError(err);
       
   919     MMPXPlaybackCallback* cb =
       
   920             static_cast<MMPXPlaybackCallback*>(iTaskQueue->Callback());
       
   921     switch(task)
       
   922         {
       
   923         case EPbsGetProperty:
       
   924             {
       
   925             iCallbackOngoing = ETrue;
       
   926             cb->HandlePropertyL(
       
   927                     static_cast<TMPXPlaybackProperty>(iTaskQueue->Param()),
       
   928                     iPropertyValuePckg(), err);
       
   929             iCallbackOngoing = EFalse;
       
   930             break;
       
   931             }
       
   932         case EPbsGetSubPlayerNamesByUid:
       
   933             {
       
   934             if (KErrNone == err)
       
   935                 {
       
   936                 CDesCArray* desArray = NULL;
       
   937                 if (iResultSizePckg())
       
   938                     {
       
   939                     ::TransferBufferFromServerL(iPbs, EPbsGetAsyncBuffer,
       
   940                                                 iResultSizePckg(), iBuffer);
       
   941                     MPXUser::CreateFromBufferL(*iBuffer, desArray);
       
   942                     CleanupStack::PushL(desArray);
       
   943                     }
       
   944                 iCallbackOngoing = ETrue;
       
   945                 cb->HandleSubPlayerNamesL(TUid::Uid(iTaskQueue->Param()),
       
   946                                           desArray, iCompletePckg(),err);
       
   947                 if (!iCompletePckg())
       
   948                     { // Add next request in the task queue, but not mess up runerror
       
   949                     TRAPD(err, SubPlayerNamesL(*cb,TUid::Uid(iTaskQueue->Param())));
       
   950                     if (KErrNone!=err)
       
   951                         { // complete searching sub players when error on request
       
   952                         cb->HandleSubPlayerNamesL(TUid::Uid(iTaskQueue->Param()),
       
   953                                                   desArray, ETrue, err);
       
   954                         }
       
   955                     }
       
   956                 iCallbackOngoing = EFalse;
       
   957                 if (desArray)
       
   958                     {
       
   959                     CleanupStack::PopAndDestroy(desArray);
       
   960                     }
       
   961                 }
       
   962             else
       
   963                 {
       
   964                 iCallbackOngoing = ETrue;
       
   965                 cb->HandleSubPlayerNamesL(TUid::Uid(iTaskQueue->Param()),
       
   966                                          NULL, ETrue, err);
       
   967                 iCallbackOngoing = EFalse;
       
   968                 }
       
   969             break;
       
   970             }
       
   971         case EPbsGetMedia:
       
   972             {
       
   973             if (iResultSizePckg() && KErrNone == err)
       
   974                 {
       
   975                 CMPXMedia* media(NULL);
       
   976                 ::TransferBufferFromServerL(iPbs, EPbsGetAsyncBuffer,
       
   977                                             iResultSizePckg(), iBuffer);
       
   978                 ::NewFromBufferL(*iBuffer, media);
       
   979                 CleanupStack::PushL(media);
       
   980                 iCallbackOngoing = ETrue;
       
   981                 cb->HandleMediaL(*media, err);
       
   982                 iCallbackOngoing = EFalse;
       
   983                 CleanupStack::PopAndDestroy(media);
       
   984                 }
       
   985             else
       
   986                 {
       
   987                 iCallbackOngoing = ETrue;
       
   988                 cb->HandleMediaL(*iMediaOnError, err); // return dummy media
       
   989                 iCallbackOngoing = EFalse;
       
   990                 }
       
   991             break;
       
   992             }
       
   993         case EPbsCommand:
       
   994             {
       
   995             CMPXCommand* result = NULL;
       
   996             if (KErrNone == err)
       
   997                 {
       
   998                 if(iResultSizePckg())
       
   999                     {
       
  1000                     ::TransferBufferFromServerL(iPbs,EPbsGetAsyncBuffer,
       
  1001                                                 iResultSizePckg(), iBuffer);
       
  1002                     ::NewFromBufferL<CMPXCommand>(*iBuffer, result);
       
  1003                     }
       
  1004                 CleanupStack::PushL(result);
       
  1005                 iCallbackOngoing = ETrue;
       
  1006                 cb->HandlePlaybackCommandComplete(result, KErrNone);
       
  1007                 iCallbackOngoing = EFalse;
       
  1008                 CleanupStack::PopAndDestroy(result);
       
  1009                 }
       
  1010             else
       
  1011                 {
       
  1012                 iCallbackOngoing = ETrue;
       
  1013                 cb->HandlePlaybackCommandComplete(NULL, err);
       
  1014                 iCallbackOngoing = EFalse;
       
  1015                 }
       
  1016             break;
       
  1017             }
       
  1018         default:
       
  1019             ASSERT(0);
       
  1020         }
       
  1021     MPX_DEBUG2("CMPXPlaybackUtility::RunL remove a task from queue 0x%08x",
       
  1022                iTaskQueue);
       
  1023     iTaskQueue->RemoveTask();
       
  1024     ExecuteNextRequest();
       
  1025     }
       
  1026 
       
  1027 // ----------------------------------------------------------------------------
       
  1028 // Canceling by the server
       
  1029 // ----------------------------------------------------------------------------
       
  1030 //
       
  1031 void CMPXPlaybackUtility::DoCancel()
       
  1032     {
       
  1033     MPX_FUNC_EX("CMPXPlaybackUtility::DoCancel()");
       
  1034 #ifdef _ENABLE_GUARD_TIMER
       
  1035     iGuardTimer->Cancel();
       
  1036 #endif
       
  1037     TRAP_IGNORE(iPbs.SendReceiveL(EPbsCancelRequest));
       
  1038     }
       
  1039 
       
  1040 // ----------------------------------------------------------------------------
       
  1041 // Sends error message to all observers - maybe it should only be to the
       
  1042 // client that calls the async method
       
  1043 // ----------------------------------------------------------------------------
       
  1044 //
       
  1045 TInt CMPXPlaybackUtility::RunError(TInt aError)
       
  1046     {
       
  1047     MPX_FUNC_EX("CMPXPlaybackUtility::RunError");
       
  1048     TRAP_IGNORE(HandleRunErrorL(aError));
       
  1049     iCallbackOngoing = EFalse;
       
  1050     MPX_DEBUG2("CMPXPlaybackUtility::RunError remove a task from queue 0x%08x",
       
  1051                iTaskQueue);
       
  1052     iTaskQueue->RemoveTask();
       
  1053     ExecuteNextRequest();
       
  1054     return KErrNone;
       
  1055     }
       
  1056 
       
  1057 // ----------------------------------------------------------------------------
       
  1058 // Distributes messages to all observers
       
  1059 // ----------------------------------------------------------------------------
       
  1060 //
       
  1061 void CMPXPlaybackUtility::MessageReceived(TInt aMsgData, TInt aError)
       
  1062     {
       
  1063     MPX_FUNC_EX("CMPXPlaybackUtility::MessageReceived()");
       
  1064     TRAP_IGNORE(HandleMessageL(aMsgData,aError));
       
  1065     }
       
  1066 
       
  1067 // ----------------------------------------------------------------------------
       
  1068 // Distributes messages to all observers
       
  1069 // ----------------------------------------------------------------------------
       
  1070 //
       
  1071 void CMPXPlaybackUtility::HandleMessageL(TInt aMsgData, TInt aError)
       
  1072     {
       
  1073     ASSERT(aMsgData>0 || aError); // aMessage should not be NULL and aError is KErrNone
       
  1074     MPX_DEBUG4("CMPXPlaybackUtility::HandleMessageL 0x%08x, MsgHandle 0x%08x, Err %d",
       
  1075                this, aMsgData, aError);
       
  1076     if (aMsgData > 0)
       
  1077         {
       
  1078         CMPXMessage* msg = CMPXMessage::NewL(aMsgData);
       
  1079         CleanupStack::PushL(msg);
       
  1080         ASSERT(msg->IsSupported(KMPXMessageGeneralId));
       
  1081         TInt id = static_cast<TInt>(
       
  1082                     msg->ValueTObjectL<TMPXMessageId>(KMPXMessageGeneralId));
       
  1083         if (id==KMPXMessageGeneral)
       
  1084             { // DEPRECATED, covert the general message into TMPXMessage
       
  1085             ASSERT(msg->IsSupported(KMPXMessageGeneralEvent));
       
  1086             TMPXPlaybackMessage::TEvent event =
       
  1087                 static_cast<TMPXPlaybackMessage::TEvent>(
       
  1088                              msg->ValueTObjectL<TInt>(KMPXMessageGeneralEvent));
       
  1089             if (event == TMPXPlaybackMessage::EActivePlayerChanged)
       
  1090                 {
       
  1091                 ASSERT(msg->IsSupported(KMPXMessageGeneralType));
       
  1092                 TInt type(msg->ValueTObjectL<TInt>(KMPXMessageGeneralType));
       
  1093                 ASSERT(msg->IsSupported(KMPXMessageGeneralData));
       
  1094                 TInt data(msg->ValueTObjectL<TInt>(KMPXMessageGeneralData));
       
  1095                 if ( type)
       
  1096                     { // receive this message because this client attached to
       
  1097                       // ActivePlayer
       
  1098                     MPX_DEBUG2("CMPXPlaybackUtility::MessageReceived 0x%08x, rebinds to active player",
       
  1099                                this);
       
  1100                     // Cancel request to old player
       
  1101                     CancelRequest();
       
  1102                     TRAP_IGNORE(iPbs.SendReceiveL(EPbsSetMode,
       
  1103                                            TIpcArgs(KPbModeActivePlayer.iUid, EMPXCategoryMusic)));
       
  1104                     }
       
  1105                 }
       
  1106             }
       
  1107         for (TInt i = iObservers.Count(); --i >= 0;)
       
  1108             {
       
  1109             iObservers[i]->HandlePlaybackMessage(msg, aError);
       
  1110             }
       
  1111         CleanupStack::PopAndDestroy(msg);
       
  1112         }
       
  1113     else
       
  1114         {
       
  1115         for (TInt i = iObservers.Count(); --i >= 0;)
       
  1116             {
       
  1117             iObservers[i]->HandlePlaybackMessage(NULL, aError);
       
  1118             }
       
  1119         }
       
  1120     iMsgMonitor->GetNextMessage();
       
  1121     }
       
  1122 
       
  1123 // ----------------------------------------------------------------------------
       
  1124 //  Handle error in RunL
       
  1125 // ----------------------------------------------------------------------------
       
  1126 //
       
  1127 void CMPXPlaybackUtility::HandleRunErrorL(TInt aError)
       
  1128     {
       
  1129     MPX_FUNC_EX("CMPXPlaybackUtility::HandleRunErrorL()");
       
  1130     TInt task = iTaskQueue->Task();
       
  1131     MMPXPlaybackCallback* cb =
       
  1132             static_cast<MMPXPlaybackCallback*>(iTaskQueue->Callback());
       
  1133     if (!iCallbackOngoing)
       
  1134         { // Error happens during preparing callback
       
  1135         iCallbackOngoing = ETrue; // will be reset to EFalse in the RunError
       
  1136         switch(task)
       
  1137             {
       
  1138             case EPbsGetProperty:
       
  1139                 {
       
  1140                 cb->HandlePropertyL(
       
  1141                         static_cast<TMPXPlaybackProperty>(iTaskQueue->Param()),
       
  1142                         0, // dummy value on error
       
  1143                         aError);
       
  1144                 break;
       
  1145                 }
       
  1146             case EPbsGetSubPlayerNamesByUid:
       
  1147                 {
       
  1148                 cb->HandleSubPlayerNamesL(TUid::Uid(iTaskQueue->Param()),
       
  1149                                           NULL, ETrue, aError);
       
  1150                 break;
       
  1151                 }
       
  1152             case EPbsGetMedia:
       
  1153                 {
       
  1154                 cb->HandleMediaL(*iMediaOnError, aError);
       
  1155                 break;
       
  1156                 }
       
  1157             case EPbsCommand:
       
  1158                 {
       
  1159                 cb->HandlePlaybackCommandComplete(iMediaOnError, aError);
       
  1160                 break;
       
  1161                 }
       
  1162             default:
       
  1163                 {
       
  1164                 ASSERT(0);
       
  1165                 break;
       
  1166                 }
       
  1167             }
       
  1168         } // do nothing if error happens during client processing callback.
       
  1169           // all callback should be changed into non-leave so that this will
       
  1170           // be never happen.
       
  1171     }
       
  1172 
       
  1173 
       
  1174 // ----------------------------------------------------------------------------
       
  1175 // Read a buffer from server
       
  1176 // ----------------------------------------------------------------------------
       
  1177 //
       
  1178 HBufC* CMPXPlaybackUtility::DesL(TInt aSize)
       
  1179     {
       
  1180     HBufC* des=NULL;
       
  1181     if (aSize)
       
  1182         {
       
  1183         ::TransferBufferFromServerL(iPbs, EPbsGetSyncBuffer, aSize, iBuffer);
       
  1184         TPtrC ptr = MPXUser::Ptr(iBuffer->Ptr(0));
       
  1185         des = ptr.AllocL();
       
  1186         }
       
  1187     return des;
       
  1188     }
       
  1189 
       
  1190 // ----------------------------------------------------------------------------
       
  1191 // Adds a sync request to the queue: if there is no outstanding request,
       
  1192 // it will be executed immediately
       
  1193 // ----------------------------------------------------------------------------
       
  1194 //
       
  1195 void CMPXPlaybackUtility::AddRequestL(TMPXPlaybackServerOp aFunction,
       
  1196                                       MMPXPlaybackCallback* aCallback/*=NULL*/,
       
  1197                                       TInt aParamData/*=0*/,
       
  1198                                       CBufBase* aBuf/*=NULL*/,
       
  1199                                       TAny* aPtr,
       
  1200                                       CBase* aAlivePtr/*=NULL*/)
       
  1201     {
       
  1202     iTaskQueue->AddTaskL(aFunction, aCallback, aParamData, aBuf, aPtr, aAlivePtr, NULL);
       
  1203     MPX_DEBUG3("CMPXPlaybackUtility::AddRequestL this 0x%08x task=%d",
       
  1204             this, aFunction);
       
  1205     if (!IsActive() && !iCallbackOngoing)
       
  1206         {
       
  1207         ExecuteNextRequest();
       
  1208         }
       
  1209     }
       
  1210 
       
  1211 // ----------------------------------------------------------------------------
       
  1212 // Executes the next request in the queue.
       
  1213 // ----------------------------------------------------------------------------
       
  1214 //
       
  1215 void CMPXPlaybackUtility::ExecuteNextRequest()
       
  1216     {
       
  1217     MPX_FUNC_EX("CMPXPlaybackUtility::ExecuteNextRequest()");
       
  1218     TInt task = iTaskQueue->Task();
       
  1219     if (KErrNotFound != task && !IsActive())
       
  1220         {
       
  1221         switch(task)
       
  1222             {
       
  1223             case EPbsGetProperty:
       
  1224                 iPbs.SendReceive(EPbsGetProperty,
       
  1225                              TIpcArgs(iTaskQueue->Param(), &iPropertyValuePckg),
       
  1226                              iStatus);
       
  1227                 break;
       
  1228             case EPbsGetSubPlayerNamesByUid:
       
  1229                 iPbs.SendReceive(EPbsGetSubPlayerNamesByUid,
       
  1230                                  TIpcArgs(iTaskQueue->Param(),
       
  1231                                           &iResultSizePckg,&iCompletePckg),
       
  1232                                  iStatus);
       
  1233                 break;
       
  1234             case EPbsGetMedia:
       
  1235                 iPbs.SendReceive(task,
       
  1236                          TIpcArgs(&iResultSizePckg,
       
  1237                          ((CMPXCommand*)(iTaskQueue->PtrData()))->Data()),
       
  1238                          iStatus);
       
  1239                 break;
       
  1240             case EPbsCommand:
       
  1241                 {
       
  1242                 iPbs.SendReceive(EPbsCommand,
       
  1243                                  TIpcArgs(iTaskQueue->Param(), //[in] Async flag
       
  1244                                           &iTaskQueue->BufData(),//[in] command
       
  1245                                           &iResultSizePckg), //[out] size of buffer
       
  1246                                  iStatus);
       
  1247                 break;
       
  1248                 }
       
  1249             default:
       
  1250                 ASSERT(0);
       
  1251             }
       
  1252     #ifdef _ENABLE_GUARD_TIMER
       
  1253          if ( iGuardTimer->IsActive() );
       
  1254              iGuardTimer->Cancel();
       
  1255          iGuardTimer->Start(KMPXGuardTimer,KMPXGuardTimer,
       
  1256                             TCallBack(GuardTimerCallback,this));
       
  1257     #endif
       
  1258          SetActive();
       
  1259          MPX_DEBUG3("CMPXPlaybackUtility::ExecuteNextRequest 0x%08x task %d ",
       
  1260                  this, task);
       
  1261         }
       
  1262     }
       
  1263 #ifdef _ENABLE_GUARD_TIMER
       
  1264 // ----------------------------------------------------------------------------
       
  1265 // Guard timer time out
       
  1266 // ----------------------------------------------------------------------------
       
  1267 //
       
  1268 TInt CMPXPlaybackUtility::GuardTimerCallback(TAny* aPtr)
       
  1269     {
       
  1270     CMPXPlaybackUtility* pb = static_cast<CMPXPlaybackUtility*>(aPtr);
       
  1271     MPX_DEBUG3("CMPXPlaybackUtility::GaurdTimerCallback this 0x%08x task=%d",
       
  1272                pb, pb->iTaskQueue->Task());
       
  1273     pb->iGuardTimer->Cancel();
       
  1274     ASSERT(0); // the function should never be called
       
  1275     return KErrNone;
       
  1276     }
       
  1277 #endif
       
  1278 
       
  1279 #ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
  1280 // ----------------------------------------------------------------------------
       
  1281 // Inititialises with a single song, may not be part of any collection
       
  1282 // ----------------------------------------------------------------------------
       
  1283 //
       
  1284 void CMPXPlaybackUtility::Init64L(RFile64& aShareableFile)
       
  1285     {
       
  1286     MPX_FUNC("CMPXPlaybackUtility::Init64L(RFile64& aShareableFile)");
       
  1287     MPX_DEBUG_THREAD("CMPXPlaybackUtility::Init64L()");
       
  1288     if (!aShareableFile.SubSessionHandle())
       
  1289         {
       
  1290         User::Leave(KErrArgument);
       
  1291         }
       
  1292     TIpcArgs args;
       
  1293     aShareableFile.TransferToServer(args,0,1);
       
  1294     iPbs.SendReceiveL(EPbsInitFromFile64,args);
       
  1295     }
       
  1296  
       
  1297 // ----------------------------------------------------------------------------
       
  1298 // Inititialises with a file, may not be part of any collection
       
  1299 // ----------------------------------------------------------------------------
       
  1300 //
       
  1301 void CMPXPlaybackUtility::InitStreaming64L(RFile64& aShareableFile, const TInt aAccessPoint)
       
  1302     {
       
  1303     MPX_FUNC("CMPXPlaybackUtility::InitStreaming64L(RFile64& aShareableFile, const TInt aAccessPoint)");
       
  1304     MPX_DEBUG_THREAD("CMPXPlaybackUtility::InitStreaming64L()");
       
  1305     if (!aShareableFile.SubSessionHandle())
       
  1306         {
       
  1307         User::Leave(KErrArgument);
       
  1308         }
       
  1309     TIpcArgs args;
       
  1310     aShareableFile.TransferToServer(args,0,1); 
       
  1311     args.Set(2, aAccessPoint);  //use index "2" for setting the AccessPoint   
       
  1312 
       
  1313     iPbs.SendReceiveL(EPbsInitStreamingFromFile64, args);
       
  1314     }
       
  1315 
       
  1316 // ----------------------------------------------------------------------------
       
  1317 // Return file handle
       
  1318 // ----------------------------------------------------------------------------
       
  1319 //
       
  1320 RFile64* CMPXPlaybackUtility::File64L()
       
  1321     {
       
  1322     MPX_FUNC_EX("CMPXPlaybackUtility::File64L()");
       
  1323     TPckgBuf<TInt> fileHandle;
       
  1324     TInt fsHandle = iPbs.SendReceiveL(EPbsGetFile64,TIpcArgs(&fileHandle));
       
  1325     RFile64* file(NULL);
       
  1326     if (KErrNotFound != fileHandle())
       
  1327         {
       
  1328         iFile64.Close();
       
  1329         User::LeaveIfError(iFile64.AdoptFromServer(fsHandle,fileHandle()));
       
  1330         file = &iFile64;
       
  1331         } // else return NULL
       
  1332     return file;
       
  1333     }
       
  1334 
       
  1335 #endif // SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
       
  1336 
       
  1337 // End of file