upnpmpxplugins/upnpplaybackplugins/src/upnpsingleton.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
parent 39 6369bfd1b60d
child 41 b4d83ea1d6e2
equal deleted inserted replaced
39:6369bfd1b60d 40:08b5eae9f9ff
     1 /*
       
     2 * Copyright (c) 2008 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:      Singleton class for main upnp related services
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDES
       
    24 #include <badesca.h>
       
    25 #include "upnpavcontrollerfactory.h"
       
    26 #include "upnpavcontroller.h"
       
    27 #include "upnpavdevice.h"
       
    28 #include "upnpavdevicelist.h"
       
    29 #include "upnprendererselectorobserver.h"
       
    30 #include "upnpsingleton.h"
       
    31 
       
    32 // CONSTANTS
       
    33 const TInt KDefaultGranularity = 5;
       
    34 const TInt32 KRendererRequestTimeOut = 5000000;
       
    35 
       
    36 _LIT( KComponentLogfile, "musicplugins.txt");
       
    37 #include "upnplog.h"
       
    38 
       
    39 // --------------------------------------------------------------------------
       
    40 // Static members of CUPnPSingleton
       
    41 // --------------------------------------------------------------------------
       
    42 //
       
    43 
       
    44 // reference count
       
    45 TInt CUPnPSingleton::iInstanceCount = 0;
       
    46 
       
    47 // reference count
       
    48 CUPnPSingleton* CUPnPSingleton::iInstance = 0;
       
    49 
       
    50 // default device index
       
    51 TInt CUPnPSingleton::iDefaultRendererIndex;
       
    52 
       
    53 
       
    54 // --------------------------------------------------------------------------
       
    55 // CUPnPSingleton::GetInstanceL
       
    56 // singleton constructor
       
    57 // --------------------------------------------------------------------------
       
    58 //
       
    59 CUPnPSingleton* CUPnPSingleton::GetInstanceL()
       
    60     {
       
    61     if( iInstanceCount == 0 )
       
    62         {
       
    63         CUPnPSingleton* self = new(ELeave) CUPnPSingleton();
       
    64         CleanupStack::PushL( self );
       
    65         self->ConstructL();
       
    66         CleanupStack::Pop( self );
       
    67         iInstance = self;
       
    68         }
       
    69 
       
    70     ++iInstanceCount;
       
    71     return iInstance;
       
    72     }
       
    73 
       
    74 // --------------------------------------------------------------------------
       
    75 // CUPnPSingleton::CUPnPSingleton
       
    76 // Default constructor.
       
    77 // --------------------------------------------------------------------------
       
    78 //
       
    79 CUPnPSingleton::CUPnPSingleton()
       
    80     {
       
    81     }
       
    82 
       
    83 // --------------------------------------------------------------------------
       
    84 // CUPnPSingleton::ConstructL
       
    85 // ConstructL.
       
    86 // --------------------------------------------------------------------------
       
    87 //
       
    88 void CUPnPSingleton::ConstructL()
       
    89     {
       
    90     // Create timer for observing play time out.
       
    91     iPeriodizer = CUPnPMusicPeriodizer::NewL( *this,
       
    92         KRendererRequestTimeOut );
       
    93 
       
    94     // Create handle to AVController
       
    95     iAVController = UPnPAVControllerFactory::NewUPnPAVControllerL();
       
    96     iAVController->SetDeviceObserver( *this );
       
    97     CacheRendererListL();
       
    98     if ( iMediaRenderers.Count() > 0 )
       
    99         {
       
   100         iSelectorState = EStateReady;
       
   101         }
       
   102     else
       
   103         {
       
   104         iSelectorState = EStateWaiting;
       
   105         iPeriodizer->Start();
       
   106         }
       
   107 
       
   108     }
       
   109 
       
   110 // --------------------------------------------------------------------------
       
   111 // CUPnPSingleton::LoseInstance
       
   112 // singleton desctuctor
       
   113 // --------------------------------------------------------------------------
       
   114 //
       
   115 void CUPnPSingleton::LoseInstance( CUPnPSingleton* aInstance )
       
   116     {
       
   117     if( aInstance != 0 )
       
   118         {
       
   119         __ASSERTD( aInstance == iInstance,__FILE__, __LINE__ );
       
   120         __ASSERTD( iInstanceCount > 0,__FILE__, __LINE__ );
       
   121         --iInstanceCount;
       
   122         if( iInstanceCount == 0 )
       
   123             {
       
   124             delete iInstance;
       
   125             iInstance = 0;
       
   126             }
       
   127         }
       
   128     }
       
   129 
       
   130 // --------------------------------------------------------------------------
       
   131 // CUPnPSingleton::~CUPnPSingleton
       
   132 // Destructor.
       
   133 // --------------------------------------------------------------------------
       
   134 //
       
   135 CUPnPSingleton::~CUPnPSingleton()
       
   136     {
       
   137     __LOG("CUPnPSingleton::~CUPnPSingleton()");
       
   138     iMediaRenderers.ResetAndDestroy();
       
   139     delete iPeriodizer;
       
   140     if( iAVController )
       
   141         {
       
   142         iAVController->Release();
       
   143         }
       
   144     }
       
   145 
       
   146 // --------------------------------------------------------------------------
       
   147 // CUPnPSingleton::GetRendererNamesL
       
   148 // Get renderes from AVController and return the renderer names.
       
   149 // --------------------------------------------------------------------------
       
   150 //  
       
   151 void CUPnPSingleton::GetRendererNamesL(
       
   152     MUPnPRendererSelectorObserver& aObserver )
       
   153     {
       
   154     __ASSERTD( iRendererselectorObserver == 0,__FILE__, __LINE__ );
       
   155     iRendererselectorObserver = &aObserver;
       
   156 
       
   157     switch( iSelectorState )
       
   158         {
       
   159         case EStateWaiting:
       
   160             {
       
   161             __LOG("GetRendererNames: waiting");
       
   162             // wait for something to happen
       
   163             }
       
   164             break;
       
   165         case EStateComplete:
       
   166             {
       
   167             __LOG("GetRendererNames: complete->ready");
       
   168             DeliverNamesToObserverL( ETrue );
       
   169             iSelectorState = EStateReady;
       
   170             }
       
   171             break;
       
   172         case EStateReady:
       
   173             {
       
   174             CacheRendererListL();
       
   175             if ( iMediaRenderers.Count() > 0 )
       
   176                 {
       
   177                 __LOG("GetRendererNames: ready");
       
   178                 DeliverNamesToObserverL( ETrue );
       
   179                 }
       
   180             else
       
   181                 {
       
   182                 __LOG("GetRendererNames: ready->waiting");
       
   183                 iSelectorState = EStateWaiting;
       
   184                 iPeriodizer->Start();
       
   185                 }
       
   186             }
       
   187             break;
       
   188         case EStateError:
       
   189             {
       
   190             __LOG("GetRendererNames: error");
       
   191             DeliverNamesToObserverL( ETrue, KErrDisconnected );
       
   192             }
       
   193             break;
       
   194         default:
       
   195             {
       
   196             __PANICD(__FILE__, __LINE__ );
       
   197             }
       
   198             break;
       
   199         }
       
   200     }
       
   201 
       
   202 // --------------------------------------------------------------------------
       
   203 // CUPnPSingleton::CancelGetRendererNames
       
   204 // --------------------------------------------------------------------------
       
   205 //
       
   206 void CUPnPSingleton::CancelGetRendererNames()
       
   207     {
       
   208     // just clear the observer -> no callbacks will occur.
       
   209     iRendererselectorObserver = 0;
       
   210     }
       
   211 
       
   212 // --------------------------------------------------------------------------
       
   213 // CUPnPSingleton::SelectRendererByIndexL
       
   214 // Select renderer by given index.
       
   215 // --------------------------------------------------------------------------
       
   216 //
       
   217 const CUpnpAVDevice* CUPnPSingleton::SelectRendererByIndexL( TInt aIndex )
       
   218     {
       
   219      if( iMediaRenderers.Count() <= aIndex || aIndex < 0 )
       
   220         {        
       
   221         __LOG("CUPnPSingl::SelectRendererByIndexL error: Wrong index");
       
   222         User::Leave( KErrArgument );
       
   223         }
       
   224         
       
   225     if ( iRendererselectorObserver != 0 )
       
   226         {
       
   227         DeliverNamesToObserverL( ETrue );
       
   228         }
       
   229 
       
   230     if ( !IsAvailable( *iMediaRenderers[aIndex] ) )
       
   231         {
       
   232         __LOG("CUPnPSingl::SelectRendererByIndexL error: disconnected");
       
   233         User::Leave( KErrDisconnected );
       
   234         }
       
   235 
       
   236     iDefaultRendererIndex = aIndex;
       
   237 
       
   238     return iMediaRenderers[aIndex];
       
   239     }
       
   240 
       
   241 // --------------------------------------------------------------------------
       
   242 // CUPnPSingleton::DefaultDevice
       
   243 // Return return pointer of current renderer
       
   244 // --------------------------------------------------------------------------
       
   245 //
       
   246 const CUpnpAVDevice* CUPnPSingleton::DefaultDevice()
       
   247     {
       
   248     if ( iDefaultRendererIndex >= 0 )
       
   249         {
       
   250         return iMediaRenderers[iDefaultRendererIndex];
       
   251         }
       
   252     else
       
   253         {
       
   254         return 0;
       
   255         }
       
   256     }
       
   257 
       
   258 // --------------------------------------------------------------------------
       
   259 // CUPnPSingleton::AVC
       
   260 // Provides reference to the AVController resource
       
   261 // --------------------------------------------------------------------------
       
   262 //
       
   263 MUPnPAVController& CUPnPSingleton::AVC()
       
   264     {
       
   265     return *iAVController;
       
   266     }
       
   267 
       
   268     
       
   269 // --------------------------------------------------------------------------
       
   270 // Method from MUPnPAVMediaObserver
       
   271 // --------------------------------------------------------------------------
       
   272 
       
   273 // --------------------------------------------------------------------------
       
   274 // CUPnPSingleton::UPnPDeviceDiscovered
       
   275 // Inform that new renderer device has discovered.
       
   276 // --------------------------------------------------------------------------
       
   277 //
       
   278 void CUPnPSingleton::UPnPDeviceDiscovered( const CUpnpAVDevice& aDevice  )
       
   279     {
       
   280     // Check if device is media renderer
       
   281     if( aDevice.DeviceType() == CUpnpAVDevice::EMediaRenderer 
       
   282         && aDevice.AudioCapability() )
       
   283         {
       
   284         if ( iSelectorState == EStateWaiting ||
       
   285              iSelectorState == EStateComplete )
       
   286             {
       
   287             CUpnpAVDevice* dev = 0;
       
   288             TRAP_IGNORE( dev = CUpnpAVDevice::NewL( aDevice ) );
       
   289             if( dev )
       
   290                 {
       
   291                 iMediaRenderers.AppendL( dev );
       
   292                 if ( iRendererselectorObserver != 0 )
       
   293                     {
       
   294                     TRAP_IGNORE( DeliverNamesToObserverL( EFalse ) );
       
   295                     }
       
   296                 }
       
   297             }
       
   298         }
       
   299     else
       
   300         {
       
   301         // Do nothing with media servers
       
   302         }
       
   303     }
       
   304 
       
   305 // --------------------------------------------------------------------------
       
   306 // CUPnPSingleton::UPnPDeviceDisappeared
       
   307 // Inform that renderer device has disappeared.
       
   308 // --------------------------------------------------------------------------
       
   309 //   
       
   310 void CUPnPSingleton::UPnPDeviceDisappeared( const CUpnpAVDevice& aDevice )
       
   311     {
       
   312     // Check if device is media renderer
       
   313     if( aDevice.DeviceType() == CUpnpAVDevice::EMediaRenderer 
       
   314         && aDevice.AudioCapability() )
       
   315         {
       
   316         if ( iSelectorState == EStateWaiting ||
       
   317              iSelectorState == EStateComplete )
       
   318             {
       
   319             // In monitoring state. Remove the renderer from cache.
       
   320             TInt count = iMediaRenderers.Count();
       
   321             for( TInt i = 0; i < count; i++ )
       
   322                 {
       
   323                 if( aDevice.Uuid().Compare(
       
   324                     iMediaRenderers[i]->Uuid() ) == 0 )
       
   325                     {
       
   326                     iMediaRenderers.Remove(i);
       
   327                     // we removed an renderer from the list so we want to 
       
   328                     // continue the loop with the same i.
       
   329                     // Could break here if absolutely sure that there are 
       
   330                     // no duplicates in iMediaRenderers.
       
   331                     count--;
       
   332                     i--; 
       
   333                     }
       
   334                 }
       
   335             if ( iRendererselectorObserver != 0 )
       
   336                 {
       
   337                 TRAP_IGNORE( DeliverNamesToObserverL( EFalse ) );
       
   338                 }
       
   339             }
       
   340         else if ( iSelectorState == EStateReady )
       
   341             {
       
   342             // Device disappears in ready state. Can't remove from cache
       
   343             // (because we use indexing to select to renderers)
       
   344             // instead mark the renderer unusable.
       
   345             __LOG( "Singleton: renderer disappeared in Ready state" );
       
   346             TInt count = iMediaRenderers.Count();
       
   347             TBool done = EFalse;
       
   348             for( TInt i = 0; i < count && !done; i++ )
       
   349                 {
       
   350                 if( aDevice.Uuid().Compare(
       
   351                     iMediaRenderers[i]->Uuid() ) == 0 )
       
   352                     {
       
   353                     SetAvailable( *iMediaRenderers[i], EFalse );
       
   354                     done = ETrue;
       
   355                     }
       
   356                 }
       
   357             }
       
   358         }
       
   359     else
       
   360         {
       
   361         // Do nothing with media servers
       
   362         }
       
   363     }
       
   364 
       
   365 // --------------------------------------------------------------------------
       
   366 // CUPnPSingleton::WLANConnectionLost
       
   367 // Inform that renderer device has disappeared.
       
   368 // --------------------------------------------------------------------------
       
   369 // 
       
   370 void CUPnPSingleton::WLANConnectionLost()
       
   371     {
       
   372     iMediaRenderers.ResetAndDestroy();
       
   373     if ( iSelectorState == EStateWaiting )
       
   374         {
       
   375         iPeriodizer->Stop();
       
   376         }
       
   377 
       
   378     iSelectorState = EStateError;
       
   379 
       
   380     if ( iRendererselectorObserver != 0 )
       
   381         {
       
   382         TRAP_IGNORE( DeliverNamesToObserverL( ETrue, KErrDisconnected ) );
       
   383         }
       
   384     }
       
   385 
       
   386 // --------------------------------------------------------------------------
       
   387 // Methods of MUPnPMusicPeriodizerObserver
       
   388 // --------------------------------------------------------------------------
       
   389 
       
   390 // --------------------------------------------------------------------------
       
   391 // CUPnPSingleton::HandlePeriod
       
   392 // Action when timer has expired.
       
   393 // --------------------------------------------------------------------------
       
   394 // 
       
   395 void CUPnPSingleton::HandlePeriod()
       
   396     {
       
   397     __ASSERTD( iSelectorState == EStateWaiting,__FILE__, __LINE__ );
       
   398 
       
   399     if ( iMediaRenderers.Count() > 0 )
       
   400         {
       
   401         __LOG("GetRendererNames: timeout->complete");
       
   402         iSelectorState = EStateComplete;
       
   403         if ( iRendererselectorObserver != 0 )
       
   404             {
       
   405             __LOG("GetRendererNames: complete->ready");
       
   406             iSelectorState = EStateReady;
       
   407             TRAP_IGNORE( DeliverNamesToObserverL( ETrue ) );
       
   408             }
       
   409         }
       
   410     else
       
   411         {
       
   412         __LOG("GetRendererNames: timeout->continue timer");
       
   413         iPeriodizer->Continue();
       
   414         if ( iRendererselectorObserver != 0 )
       
   415             {
       
   416             TRAP_IGNORE( DeliverNamesToObserverL( ETrue ) );
       
   417             }
       
   418         }
       
   419     }
       
   420 
       
   421 // --------------------------------------------------------------------------
       
   422 // Private methods of CUPnPRendererSelector
       
   423 // --------------------------------------------------------------------------
       
   424 
       
   425 // --------------------------------------------------------------------------
       
   426 // CUPnPSingleton::CacheRendererListL
       
   427 // Refreshes the renderer cache from AVController
       
   428 // --------------------------------------------------------------------------
       
   429 // 
       
   430 void CUPnPSingleton::CacheRendererListL()
       
   431     {
       
   432     // Clean old devices array and device names
       
   433     iDefaultRendererIndex = KErrNotFound;
       
   434 
       
   435     // Get media renderers
       
   436     CUpnpAVDeviceList* devices = iAVController->GetMediaRenderersL();
       
   437     CleanupStack::PushL( devices );
       
   438 
       
   439     // go through current renderer list
       
   440     for ( TInt i = 0; i < iMediaRenderers.Count(); ++i )
       
   441         {
       
   442         CUpnpAVDevice* renderer = iMediaRenderers[ i ];
       
   443         TBool exists = EFalse;
       
   444         for ( TInt j = 0; j < devices->Count() && !exists; ++j )
       
   445             {
       
   446             CUpnpAVDevice* device = (*devices)[j];
       
   447             if ( renderer->Uuid() == device->Uuid())
       
   448                 {
       
   449                 // renderer still exists.
       
   450                 delete device;
       
   451                 devices->Remove( j );
       
   452                 SetAvailable( *renderer, ETrue );
       
   453                 --j;
       
   454                 exists = ETrue;
       
   455                 }
       
   456             }
       
   457         if ( !exists )
       
   458             {
       
   459             // renderer has disappeared
       
   460             delete renderer;
       
   461             iMediaRenderers.Remove( i );
       
   462             --i;
       
   463             }
       
   464         }
       
   465 
       
   466     // Remaining devices are all new. Add them to end of the list.
       
   467     while ( devices->Count() > 0 )
       
   468         {
       
   469          __LOG("CacheRendererListL::Remaining devices are all new.");
       
   470         CUpnpAVDevice* device = (*devices)[ 0 ];
       
   471         if( device->AudioCapability() )
       
   472             {
       
   473             iMediaRenderers.AppendL( device );
       
   474             }
       
   475         devices->Remove( 0 );
       
   476         }
       
   477 
       
   478     CleanupStack::PopAndDestroy( devices ); 
       
   479     }
       
   480 
       
   481 // --------------------------------------------------------------------------
       
   482 // CUPnPSingleton::DeliverNamesToObserverL
       
   483 // Delivers current names in cached list to observer
       
   484 // --------------------------------------------------------------------------
       
   485 // 
       
   486 void CUPnPSingleton::DeliverNamesToObserverL( TBool aCompleted,
       
   487     TInt aError )
       
   488     {
       
   489     __ASSERTD( iRendererselectorObserver != 0,__FILE__, __LINE__ );
       
   490 
       
   491     // Create an array for names
       
   492     CDesCArrayFlat* deviceNames = new(ELeave) CDesCArrayFlat( 
       
   493         KDefaultGranularity );
       
   494     CleanupStack::PushL( deviceNames );
       
   495 
       
   496     TInt count = iMediaRenderers.Count();
       
   497     for( TInt i = 0; i < count; i++ )
       
   498         {
       
   499         HBufC* buf = HBufC::NewL(
       
   500             iMediaRenderers[i]->FriendlyName().Length() );
       
   501         CleanupStack::PushL( buf );
       
   502         buf->Des().Copy( iMediaRenderers[i]->FriendlyName() );
       
   503         deviceNames->AppendL( *buf ); // Transfer ownership
       
   504         CleanupStack::PopAndDestroy( buf );
       
   505         }
       
   506 
       
   507     // Call back current renderer names
       
   508     __LOG1( "DeliverNamesToObserver: count=%d", count );
       
   509     MUPnPRendererSelectorObserver& obs = *iRendererselectorObserver;
       
   510     iRendererselectorObserver = 0;
       
   511     obs.HandleSubPlayerNames( deviceNames, aCompleted, aError );
       
   512 
       
   513     CleanupStack::PopAndDestroy( deviceNames );
       
   514     }
       
   515 
       
   516 // --------------------------------------------------------------------------
       
   517 // CUPnPSingleton::IsAvailable
       
   518 // checks if the device type is renderer
       
   519 // --------------------------------------------------------------------------
       
   520 // 
       
   521 TBool CUPnPSingleton::IsAvailable( const CUpnpAVDevice& aDevice ) const
       
   522     {
       
   523     return aDevice.DeviceType() == CUpnpAVDevice::EMediaRenderer;
       
   524     }
       
   525 
       
   526 // --------------------------------------------------------------------------
       
   527 // CUPnPSingleton::SetAvailable
       
   528 // sets the device type to an illegal unrecognized type
       
   529 // --------------------------------------------------------------------------
       
   530 // 
       
   531 void CUPnPSingleton::SetAvailable(
       
   532     CUpnpAVDevice& aDevice, TBool aAvailable ) const
       
   533     {
       
   534     if ( aAvailable && !IsAvailable( aDevice ) )
       
   535         {
       
   536         __LOG1( "CUPnPSingleton: renderer available: %S",
       
   537             &aDevice.FriendlyName() );
       
   538         aDevice.SetDeviceType(
       
   539             CUpnpAVDevice::EMediaRenderer );
       
   540         }
       
   541     else if ( !aAvailable && IsAvailable ( aDevice ) )
       
   542         {
       
   543         __LOG1( "CUPnPSingleton: renderer not available: %S",
       
   544             &aDevice.FriendlyName() );
       
   545         aDevice.SetDeviceType(
       
   546             (CUpnpAVDevice::TUpnpAVDeviceType)KErrUnknown );
       
   547         }
       
   548     }