homesync/contentmanager/homesyncgsplugin/src/mssettingitemdevices.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:52:00 +0200
changeset 0 7f85d04be362
permissions -rw-r--r--
Revision: 200947 Kit: 200951

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  CMSSettingItemDevices class implementation
*
*/


#include <msgspluginsrc.rsg>
#include <StringLoader.h>
#include "upnpavdevice.h"
#include "upnpavcontroller.h" // for MUPnPAVController
#include "upnpavcontrollerfactory.h" // for UPnPAVControllerFactory
#include <AknWaitDialog.h>
#include <utf.h> // for CnvUtfConverter

#include "cmmediaserverfull.h"
#include "cmcommonutils.h"
#include <aknnotewrappers.h>
#include "mssettingitemdevices.h"
#include "msmultiselectionpopup.h"
#include "msengine.h"
#include "upnpavdevicelist.h"
#include "msdebug.h"

// CONSTANTS

// reserved list size
const TInt KItemArrayGranularity = 3;

// ================= MEMBER FUNCTIONS =======================

// --------------------------------------------------------------------------
// CMSSettingItemDevices::NewL
// --------------------------------------------------------------------------
//
CMSSettingItemDevices* CMSSettingItemDevices::NewL(
                        TInt aIdentifier,
                        TDes& aText,
                        CMSEngine& aMSEngine,
                        RPointerArray<CCmMediaServerFull>& aStoredServers,
                        TBool aUploadCapabilitySupport )
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::NewL"));

    CMSSettingItemDevices* self = CMSSettingItemDevices::NewLC(
                                          aIdentifier,
                                          aText,
                                          aMSEngine,
                                          aStoredServers,
                                          aUploadCapabilitySupport );

    CleanupStack::Pop( self );
    return self;
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::NewLC
// --------------------------------------------------------------------------
//
CMSSettingItemDevices* CMSSettingItemDevices::NewLC(
                        TInt aIdentifier,
                        TDes& aText,
                        CMSEngine& aMSEngine,
                        RPointerArray<CCmMediaServerFull>& aStoredServers,
                        TBool aUploadCapabilitySupport )
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::NewLC"));
	
    CMSSettingItemDevices* self = new ( ELeave ) CMSSettingItemDevices(
                                          aIdentifier,
                                          aText,
                                          aMSEngine,
                                          aStoredServers,
                                          aUploadCapabilitySupport );

    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }
	
// --------------------------------------------------------------------------
// CMSSettingItemDevices::ConstructL
// --------------------------------------------------------------------------
//
void CMSSettingItemDevices::ConstructL()
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::ConstructL begins"));

    iSettingText = HBufC::NewL( KMaxFileName );

    iSelectedServers =
        new (ELeave) CArrayFixFlat<TInt>( KItemArrayGranularity );
    
    SetSettingItemTextL();

    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::ConstructL ends"));
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::~~CMSSettingItemDevices()
// --------------------------------------------------------------------------
//
CMSSettingItemDevices::~CMSSettingItemDevices()
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::~CMSSettingItemDevices"));

    delete iSettingText;

    delete iSelectedServers;

    iServerList.Reset();
    iServerList.Close();
    
    if ( iAvController )
        {
        iAvController->RemoveDeviceObserver();
		iAvController->Release();
		iAvController = NULL;
        }

    if ( iWaitDialog )
        {
        TRAP_IGNORE( iWaitDialog->ProcessFinishedL() );
        iWaitDialog = NULL;
        }

    if ( iWait.IsStarted() )
        {
        iWait.AsyncStop();
        }

    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::EditItemL( TBool aCalledFromMenu )
// --------------------------------------------------------------------------
//
void CMSSettingItemDevices::EditItemL( TBool /*aCalledFromMenu*/ )
    {
    LOG( _L("[MSGSPlugin]\t CMSSettingItemDevices::EditItemL") );

    // restore original state
    SetAcceptState( EFalse );

    // Create list for selection
    ReadServerListL();

    // Create Avcontroller and fetch already discovered devices from it.
    CreateAvcAndFetchDevicesL();           
            
    if( !iUserCancelledSearch )
        {
        if ( iUploadCapabilitySupport )
            {
            iDevSelectionDlg = CMSMultiselectionPopup::NewL(
                                    iUploadCapabilitySupport,
                                    &iServerList,
                                    iSelectedServers );
            iDevSelectionDlg->PrepareLC(
                            R_MS_TARGET_DEVICE_SELECTION_DIALOG );
            }
        else
            {
            iDevSelectionDlg = CMSMultiselectionPopup::NewL(
                                    iUploadCapabilitySupport,
                                    &iServerList,
                                    iSelectedServers );           
            iDevSelectionDlg->PrepareLC(
                            R_MS_SOURCE_DEVICE_SELECTION_DIALOG );
            }            

        #ifndef __WINS__
            iDevSelectionDlg->QueryHeading()->SetHeaderAnimationL(
                R_MSGS_ANIMATION_FOR_SELECTION_DIALOG );
        #endif

        TInt returnValue = iDevSelectionDlg->RunLD();            

        iDevSelectionDlg = NULL;
        
        CancelDeviceSearch();

        if( returnValue )
            {
            // User presses OK
            SetAcceptState( ETrue );

            SetServersActivity();
            SetSettingItemTextL();

            iMSEngine.SetMediaServersL( iStoredServers );

            LoadL();
            UpdateListBoxTextL();
            }
        }
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::SetServersActivity
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::SetServersActivity()
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::SetServersActivity \
    begins"));

    // Set all servers inactive
    for( TInt ind=0; ind < iStoredServers.Count(); ind++ )
        {
        CCmMediaServerFull* server = iStoredServers[ind];

        if ( iUploadCapabilitySupport )
            {
            server->SetStoreUsage( EFalse );
            }
        else
            {            
            server->SetFillUsage( EFalse );
            }
            
        if ( !server->StoreUsage() && !server->FillUsage() )
            {
            server->SetIsActive( EFalse );	
            }
        }

    // Set selected servers active
    if( iSelectedServers )
        {
        // loop trough selected servers
        for ( TInt iy = 0; iy < iSelectedServers->Count(); iy++ )
            {

            // Look for the server in selection array
            TInt selectedIndex = iSelectedServers->At( iy );
            // server points to iStoredServers table
            CCmMediaServerFull* server = iServerList[selectedIndex];
           
            if ( iUploadCapabilitySupport )
                {
                server->SetStoreUsage( ETrue );
                }
            else // fill server
                {
                server->SetFillUsage( ETrue );
                }
            server->SetIsActive( ETrue );
            }
        }

    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::SetServersActivity \
    ends"));
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::CMSSettingItemDevices
// --------------------------------------------------------------------------
//
CMSSettingItemDevices::CMSSettingItemDevices( TInt aIdentifier, TDes& aText,
    CMSEngine& aMSEngine,
    RPointerArray<CCmMediaServerFull>& aStoredServers,
    TBool aUploadCapabilitySupport  ):
    CMSTextSettingItem( aIdentifier, aText ),
    iMSEngine( aMSEngine ),
    iStoredServers( aStoredServers ),
    iUploadCapabilitySupport( aUploadCapabilitySupport )
    {
    LOG( _L("[MSGSPlugin]\t CMSSettingItemDevices::CMSSettingItemDevices") );
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::ReadServerListL
//
// --------------------------------------------------------------------------
//
void CMSSettingItemDevices::ReadServerListL()
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::ReadServerListL"));

    // delete old ones
    iServerList.Reset();

    for ( TInt i = 0; i < iStoredServers.Count(); i++ )
        {
        // Add selected/marked servers to list
        if (iUploadCapabilitySupport && iStoredServers[i]->CopyCapability()
                && iStoredServers[i]->StoreUsage() )
            {
            // Add selected target servers
            iServerList.AppendL(iStoredServers[i]);
            }
        else if (!iUploadCapabilitySupport && iStoredServers[i]->FillUsage() )
            {
            // Add selected source servers
            iServerList.AppendL(iStoredServers[i]);
            }
        else
            {
            LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::ReadServerListL \
            Not selected servers should not show to user"));
            }
        }
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::SetSettingItemTextL
// Sets setting item secondary text according to selected items
// --------------------------------------------------------------------------
//
void CMSSettingItemDevices::SetSettingItemTextL()
    {
    LOG( _L("[MSGSPlugin]\t CMSSettingItemDevices::SetSettingItemTextL") );
    
    // count how many active devices threre are
    TInt count = CountSelectedItems();
    HBufC* itemText = NULL;

    if ( count == 1 )
        {
        // one active found - need to get server name
        for ( TInt index = 0; index < iStoredServers.Count(); index++ )
            {
            CCmMediaServerFull* server = iStoredServers[index];

            if ( ( iUploadCapabilitySupport && server->StoreUsage() ) ||
                 ( !iUploadCapabilitySupport && server->FillUsage() ) )
                {
                itemText = CnvUtfConverter::ConvertToUnicodeFromUtf8L(                                                
                                                server->MediaServerName() );
                CleanupStack::PushL(itemText);

                iSettingText->Des().Copy( itemText->Left( KMaxFileName) );

                CleanupStack::PopAndDestroy( itemText );
                index = iStoredServers.Count(); // break loop                
                }
            else
                {
                LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::\
                SetSettingItemTextL copycapability required but not \
                supported by server"));
                }
            }
        }
    // more than one item selected
    else
        {
        if ( count > 1 )
            {
            itemText = StringLoader::LoadLC( R_MS_ITEM_DEVICES, count );
            }
        else
            {
            itemText = StringLoader::LoadLC( R_MS_NO_SERVER_SELECTED );
            }

        // do number conversion
        TPtr ptr = itemText->Des();
        AknTextUtils::DisplayTextLanguageSpecificNumberConversion( ptr );

        iSettingText->Des().Copy( *itemText );
        CleanupStack::PopAndDestroy( itemText );
        }

     // Set new value
     SetExternalText( *iSettingText );
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::CountSelectedItems
// Counts selected items
// --------------------------------------------------------------------------
//
TInt CMSSettingItemDevices::CountSelectedItems() const
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::CountSelectedItems"));

    TInt count(0);

    if( iStoredServers.Count() )
        {
        TRACE(Print(_L("[MSGSPlugin]\t server COUNT:  = %d"),
            iStoredServers.Count() ));
        for ( TInt index = 0; index < iStoredServers.Count(); index++ )
            {

            CCmMediaServerFull* server = iStoredServers[index];

            if ( iUploadCapabilitySupport && server->StoreUsage() )
                {
                count++;
                }
            else if ( !iUploadCapabilitySupport && server->FillUsage() )
                {
                count++;
                }
            else
                {
                LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::\
                CountSelectedItems server not used"));
                }
            }
        }
    TRACE(Print(_L("[MSGSPlugin]\t active server COUNT:  = %d"),
    count ));
    return count;
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::DialogDismissedL
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::DialogDismissedL( TInt aButtonId )
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::DialogDismissedL"));

    if( aButtonId != EAknSoftkeyDone )
        {
        LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::\
        DialogDismissedL CANCEL"));
        iUserCancelledSearch = ETrue;
        // cancel server search if it was started
        CancelDeviceSearch();
        }

    if ( iWait.IsStarted() )
        {
        iWait.AsyncStop();
        }
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::UPnPDeviceDiscoveredL
// Returns discovered device from UPnP AV control point.
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::UPnPDeviceDiscoveredL(
                                    const CUpnpAVDevice& aDevice)
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::UPnPDeviceDiscoveredL"));

    // Check that this is mediaserver
    if ( aDevice.DeviceType() == CUpnpAVDevice::EMediaServer &&
         aDevice.SearchCapability() && aDevice.DlnaCompatible() )
        {
        LOG(_L("[MSGSPlugin]\t Found device is Media server!"));

#ifdef __DEBUG
        HBufC* devName = UpnpString::ToUnicodeL( aDevice.FriendlyName() );
        TRACE(Print(_L("[MSGSPlugin]\t device Name= %S"), devName ));
        delete devName;
#endif
        TPtrC8 deviceUDN = aDevice.Uuid();

        TInt serverCount = iStoredServers.Count();
        TBool newServer( ETrue );
        CCmMediaServerFull* tempServer = NULL;

        // Check if server is already on the list
        for ( TInt i=0; i < serverCount; i++ )
            {
            // Compare server udn
            if ( deviceUDN.Compare(
                    iStoredServers[i]->MediaServer() ) == 0 )
                {
                tempServer = iStoredServers[i];
                // server already on the list
                i = serverCount; // end loop
                newServer = EFalse;
                }
            }

        if ( newServer )
            {
            tempServer = CCmMediaServerFull::NewL();
            CleanupStack::PushL( tempServer );
            tempServer->SetUDNL( aDevice.Uuid() );
            tempServer->SetMediaServerNameL( aDevice.FriendlyName() );
            tempServer->SetCopyCapability( aDevice.CopyCapability() );
            
            // Add the server to found list            
            iStoredServers.Append( tempServer );
            
            CleanupStack::Pop( tempServer );
            }
        // Add unselected servers to show to user
        if ( ( iUploadCapabilitySupport && tempServer->CopyCapability()
              && !tempServer->StoreUsage() )
             || ( !iUploadCapabilitySupport && !tempServer->FillUsage() ) )
            {
            iServerList.AppendL( tempServer );
            if ( iWaitDialog )
                {
                TRAP_IGNORE( iWaitDialog->ProcessFinishedL() );
                iWaitDialog = NULL;
                }

            // If devices are searched for the first time
            // the dialog needs to be created in EditItemL.
            // This call is for updating existing dialog.
            if ( iDevSelectionDlg )
                {
                iDevSelectionDlg->UpdateAndDrawPopupL( tempServer );
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::UPnPDeviceDiscovered
// Returns discovered device from UPnP AV control point
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::UPnPDeviceDiscovered(
                                    const CUpnpAVDevice& aDevice )
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::\
             UPnPDeviceDiscovered"));

    TRAP_IGNORE( UPnPDeviceDiscoveredL( aDevice ) );       
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::UPnPDeviceDisappeared
// Returns disappeared device from UPnP AV control point.
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::UPnPDeviceDisappeared(
                                    const CUpnpAVDevice& /*aDevice*/ )
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::\
             UPnPDeviceDisappeared"));
    // do nothing
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::WLANConnectionLost
// Notifies wlan connection lost
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::WLANConnectionLost()
    {
    LOG(_L("[MSGSPlugin]\t CMSSettingItemDevices::WLANConnectionLost"));
    
    TRAP_IGNORE( DialogDismissedL( EAknSoftkeyCancel ) );
    if ( iWaitDialog )
        {
        TRAP_IGNORE( iWaitDialog->ProcessFinishedL() );
        iWaitDialog = NULL;
        }
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::CreateAvcontrollerL
//
// --------------------------------------------------------------------------
//
TInt CMSSettingItemDevices::CreateAvcontrollerL()
    {
    LOG( _L("[MSGSPlugin]\t CMSSettingItemDevices::CreateAvcontrollerL" ) );

    if( iAvController )
        {
        iAvController->Release();
        iAvController = NULL;
        }

    iAvController = UPnPAVControllerFactory::NewUPnPAVControllerL();

    if( iAvController )
        {
        iAvController->SetDeviceObserver( *this );
        }

    return KErrNone;
    }

// --------------------------------------------------------------------------
// CMSSettingItemDevices::CancelDeviceSearch
//
// --------------------------------------------------------------------------
//
void CMSSettingItemDevices::CancelDeviceSearch()
    {
    LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::CancelDeviceSearch" ) );

    if ( iAvController )
        {
        iAvController->RemoveDeviceObserver();
		iAvController->Release();
		iAvController = NULL;
        }
    }
    
// ---------------------------------------------------------------------------
// CMSSettingItemDevices::FetchAlreadyDiscoveredDevicesL
// Fetches devices from AVController and calls
// DeviceDiscovered-callback for each of them.
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::FetchAlreadyDiscoveredDevicesL()
    {
    LOG( _L("[MSGSPlugin]\t CMSSettingItemDevices::\
    FetchAlreadyDiscoveredDevicesL") );
    
    // If iAvController is not created, this method is unusable. 
    // Call CreateAvControllerL first.
    User::LeaveIfNull( iAvController );
    
    // Fetch already found devices from AVController.
    CUpnpAVDeviceList* discoveredDevices = 
        iAvController->GetMediaServersL();
    CleanupStack::PushL( discoveredDevices );
        
    if ( discoveredDevices && discoveredDevices->Count() > 0 ) 
        {
        // the AVController already has some devices.
        LOG(_L("[MSGSPlugin]\t \
                CMSSettingItemDevices::FetchAlreadyDiscoveredDevicesL: \
                AVController has already discovered devices" ) );

        // process the already existing devices
        for ( TInt i = 0 ; i < discoveredDevices->Count() ; i++ ) 
            {
            UPnPDeviceDiscovered( 
                *( discoveredDevices->operator[](i) ) );
            }
        }

    // clean up        
    CleanupStack::PopAndDestroy( discoveredDevices );
    discoveredDevices = NULL;
    }
    
// ---------------------------------------------------------------------------
// CMSSettingItemDevices::CreateAvcAndFetchDevicesL
// Creates AVController, fetches devices from it and calls
// DeviceDiscovered-callback for each of them. Starts wait note if no devices 
// are already discovered.
// ---------------------------------------------------------------------------
//
TInt CMSSettingItemDevices::CreateAvcAndFetchDevicesL()
    {
    LOG( _L(
        "[MSGSPlugin]\t CMSSettingItemDevices::CreateAvcAndFetchDevicesL" )
       );
    
    iUserCancelledSearch = EFalse;

    if( iSelectedServers )
        {
        iSelectedServers->Reset();
        delete iSelectedServers;
        iSelectedServers = NULL;
        }
    iSelectedServers =
            new (ELeave) CArrayFixFlat<TInt>( KItemArrayGranularity );

    iCreateAvCState = EPhaseNotActive;
    CAknWaitNoteWrapper* waitNoteWrapper = CAknWaitNoteWrapper::NewL();
    CleanupStack::PushL( reinterpret_cast<CBase*>( waitNoteWrapper ) );
    TRAPD( err, waitNoteWrapper->ExecuteL(
              R_MS_WAIT_FOR_CREATEAVC_DIALOG,
              *this,
              ETrue ) );//ETrue = show immediately
    CleanupStack::PopAndDestroy( waitNoteWrapper );


    if ( iAvController )
        {
        // Process devices that AVController has already discovered.
        FetchAlreadyDiscoveredDevicesL();

        // If still no devices discovered, start wait note.
        if ( iServerList.Count() == 0 )
            {
            iWaitDialog = new ( ELeave ) CAknWaitDialog(
            ( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ) ) );
            iWaitDialog->SetCallback( this );
            iWaitDialog->ExecuteLD( R_MS_WAIT_DIALOG );
            LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::\
            CreateAvcAndFetchDevicesL starting wait" ) );
            iWait.Start(); // wait here until first server is found.
            }
        }
    else
        {
        //handle the error
        if( KErrDiskFull == err )
            {
            ShowErrorNoteL( R_MS_GS_MEMORY_FULL );
            }
        iUserCancelledSearch = ETrue; // Don't show selection dialog.
        }

    return err;
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::ShowErrorNoteL
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::ShowErrorNoteL( TInt aTextResource )
    {
    LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::ShowErrorNoteL" ) );
    HBufC* warningText =
                      StringLoader::LoadLC( aTextResource );
    CAknErrorNote* dlg = new ( ELeave ) CAknErrorNote( );
    dlg->ExecuteLD( *warningText );
    CleanupStack::PopAndDestroy( warningText );
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::StepL
// ---------------------------------------------------------------------------
//
void CMSSettingItemDevices::StepL()
    {
    LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::StepL" ) );
    if( EPhaseNotActive == iCreateAvCState )
        {
        CreateAvcontrollerL();
        iCreateAvCState = EPhaseCompleted;
        }
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::IsProcessDone
// ---------------------------------------------------------------------------
//
TBool CMSSettingItemDevices::IsProcessDone() const
    {
    LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::IsProcessDone" ) );
    TBool ret( EFalse );
    if ( EPhaseNotActive == iCreateAvCState )
        {
        // try to start avcontroller
        }
    else if ( EPhaseCompleted  == iCreateAvCState )
        {
        ret = ETrue;
        }
    else
        {
        LOG( _L( "[MSGSPlugin]\t CMSSettingItemDevices::IsProcessDone \
        other branch" ) );
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// CMSSettingItemDevices::CycleError
// handles the error
// ---------------------------------------------------------------------------
//
TInt CMSSettingItemDevices::CycleError( TInt aError )
    {
    TRACE( Print( _L( " CMSSettingItemDevices::CycleError \
            aError = %d " ), aError ) );

    return aError;
    }

// End of File