upnpframework/upnpfiletransferengine/src/upnpuploadhandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 00:34:14 +0300
changeset 35 f37b1259bd7b
parent 0 7f85d04be362
permissions -rw-r--r--
Revision: 201037 Kit: 201039

/*
* Copyright (c) 2007 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:  Implementation of the CUpnpUploadHandler class
*
*/


// INCLUDE FILES
// System
#include <AknUtils.h>                           // CEikonEnv
#include <bautils.h>                            // BaflUtils

// upnpframework / avcontroller api
#include "upnpavcontrollerfactory.h"            // UPnPAVControllerFactory
#include "upnpavcontroller.h"                   // MUPnPAVController
#include "upnpavbrowsingsession.h"              // MUPnPAVBrowsingSession
#include "upnpfileuploadsession.h"              // MUPnPFileDownloadSession

// upnpframework / avcontroller helper api
#include "upnpfileutility.h"                    // IsFileProtectedL()

// filetransferengine internal
#include "upnpnotehandler.h"                 
#include "upnpuploadhandler.h"


_LIT( KComponentLogfile, "filetransferengine.txt");
#include "upnplog.h"

// CONSTANTS
const TInt KZero =                      0;   
const TInt KProgressBaseValue =         100;

const TInt KUploadItemValue =           1;

// --------------------------------------------------------------------------
// CUpnpUploadHandler::NewL
// NewL.
// --------------------------------------------------------------------------
//
CUpnpUploadHandler* CUpnpUploadHandler::NewL(
                            MUPnPAVBrowsingSession* aBrowsingSession )
    {
    __LOG( "[CUpnpUploadHandler] CUpnpUploadHandler: NewL" );

    // Check that the browsing session is valid and has target device set.
    if( !aBrowsingSession )
        {
        User::Leave( KErrArgument );
        }

    CUpnpUploadHandler* self = NULL;
    self = new (ELeave) CUpnpUploadHandler;
    CleanupStack::PushL( self );
    self->ConstructL( aBrowsingSession );
    CleanupStack::Pop( self );
    __LOG( "[CUpnpUploadHandler] CUpnpUploadHandler: NewL end" );
    return self;
    }

// --------------------------------------------------------------------------
// Constuctor
// --------------------------------------------------------------------------
//
CUpnpUploadHandler::CUpnpUploadHandler()
    : CAsyncOneShot( EPriorityStandard )
    {
    __LOG( "[CUpnpUploadHandler] Constructor" );
    iUploadFirst = ETrue;
    iCopiedFileStillInArray = EFalse; 
    iDrmFilesSkipped = EFalse;
    }

// --------------------------------------------------------------------------
// Destructor
// --------------------------------------------------------------------------
//
CUpnpUploadHandler::~CUpnpUploadHandler()
    {
    __LOG( "[CUpnpUploadHandler] Destructor" );

    // If upload session is running, stop it
    if( iAvController &&
         iUploadSession)
        {
        iAvController->StopUploadSession( *iUploadSession );
        }

    // Delete the note handler.
    delete iNoteHandler;

    // delete the UpnpAvControllerClient
    delete iAvController;
    
    TInt i = 0;
    while( i < iObjectsToCopy->Count() )
        {
        if( (*iObjectsToCopy)[i] == NULL )
            {
            iObjectsToCopy->Remove( i );
            }
        else
            {
            i++;
            }    
        }
    
    __LOG1( "[CUpnpUploadHandler] copied %d", iTotalCount-iObjectsToCopy->Count() );
    iObjectsToCopy->Compress();
    __LOG( "[CUpnpUploadHandler] Destructor end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::ConstructL
// Second phase constructor
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::ConstructL(
                             MUPnPAVBrowsingSession* aBrowsingSession )
    {
    __LOG( "[CUpnpUploadHandler] ConstructL" );

    if( !aBrowsingSession )
        {
        User::Leave( KErrArgument );
        }

    // Leave if UI context is not available
    iCoeEnv = CEikonEnv::Static(); // Not owned
    if( !iCoeEnv )
        {
        User::Leave( KErrNotSupported );
        }
        
        
    // Store the browsing session
    iBrowsingSession = aBrowsingSession;

    // Create UpnpAvControllerClient
    iAvController = UPnPAVControllerFactory::NewUPnPAVControllerL();

    // Create upload session
    iUploadSession = &iAvController->StartUploadSessionL(
                                            iBrowsingSession->Device() );

    // Set this object to be the upload session observer
    iUploadSession->SetObserver( *this );

    iNoteHandler = CUpnpNoteHandler::NewL( this );
    __LOG( "[CUpnpUploadHandler] ConstructL end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::UploadItemsL
// Uploads the given objects to the remote server
// (setting in the Home Media application).
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::UploadItemsL( RPointerArray<TDesC16>* aObjectIds,
                                       TUpnpFileUploadMode aFileUploadMode )
    {
    __LOG( "[CUpnpUploadHandler] UploadItemsL" );
    // Check parameter
    if( aObjectIds->Count() <= 0 )
        {
        User::Leave( KErrArgument );
        }
    
    iUploadMode = aFileUploadMode;
    iObjectsToCopy = aObjectIds;
    
    iTotalCount = iObjectsToCopy->Count();

    // Initialise values
    iCopyPosition = -1;
    iCopyCompleteness = KZero;
    iCopiedFileStillInArray = EFalse;
    
    iStatusCode = KErrNone;
   
    // Start uploading the objects
    TRAP( iStatusCode, StartUploadL() );

    if( iStatusCode == KErrNone )
        {
        if( iUploadMode == EUpnpMove )
            {
            iNoteHandler->RunProgressNoteL( EUpnpMoveProgressNote );
            }
        else
            {
            iNoteHandler->RunProgressNoteL( EUpnpCopyProgressNote );
            }
        }
    
     /**
     * If the user cancels the copy there might be a situation 
     * where the file has just been uploaded successful but the 
     * TransferComplete is not called. 
     * In this case we need to delete that file from iObjectsToCopy.
     */

    if ( iStatusCode == KErrCancel )
        {
        if( iCopiedFileStillInArray )
            {                                           
            delete (*iObjectsToCopy)[iUploadItems];
            (*iObjectsToCopy)[iUploadItems] = NULL;  
            
            }
        }    
       
    
    // Leave if there was an error
    if( iStatusCode != KErrNone )
        {
        __LOG1( "[CUpnpUploadHandler] UploadItemsL leave %d", iStatusCode );
        User::Leave( iStatusCode );
        }
    
     
    __LOG( "[CUpnpUploadHandler] UploadItemsL end" );    
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::UploadPlayListL
// Uploads the given playlist to the remote server
// (setting in the Home Media application).
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::UploadPlayListL(
                                     const TDesC& /*aPlaylistName*/,
                                     RPointerArray<TDesC16>* aObjectPaths,
                                     TUpnpFileUploadMode aFileUploadMode )
    {
    __LOG( "[CUpnpUploadHandler] UploadPlayListL" );
    UploadItemsL( aObjectPaths, aFileUploadMode );
    __LOG( "[CUpnpUploadHandler] UploadPlayListL end" );    
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::DialogDismissedL
// ProgressDialog call back method. Get's called when a dialog is
// dismissed.
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::DialogDismissedL( )
    {
    __LOG( "[UpnpDownloadHandler] DialogDismissedL" );
    // Update the status code
    if( iStatusCode == KErrNone )
        {
        iStatusCode = KErrCancel;
        }
    
    iUploadSession->CancelAllTransfers();
    __LOG( "[UpnpDownloadHandler] DialogDismissedL end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::MediaServerDisappeared
// --------------------------------------------------------------------------
//    
void CUpnpUploadHandler::MediaServerDisappeared( 
                                    TUPnPDeviceDisconnectedReason aReason )
    {
    __LOG( "[UpnpDownloadHandler]\t MediaServerDisappeared()" );

    // Update the status code
    if( aReason == EDisconnected )
        {
        iStatusCode = KErrSessionClosed;
        }
    else if( aReason == EWLANLost )
        {
        iStatusCode = KErrDisconnected;
        }
    else
        {
        iStatusCode = KErrUnknown;
        }

    // Finish the progress note
    iNoteHandler->FinishProgressNote();
    
    __LOG( "[UpnpDownloadHandler]\t MediaServerDisappeared() end" );
    }
// --------------------------------------------------------------------------
// CUpnpUploadHandler::TransferStarted
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::TransferStarted( TInt aKey, TInt aStatus )
    {
    __LOG1( "[CUpnpUploadHandler] TransferStarted() aKey %d", aKey );
    
    if( !iProgressBarMaxValueSet )
        {
        iNoteHandler->SetMaxValue( iTotalCount * KProgressBaseValue );
        iProgressBarMaxValueSet = ETrue;
        }
    
    
    if( aStatus != KErrNone)
        {
        iStatusCode = aStatus;    
        }
    else if( aKey < 0 || aKey > iCopyPosition )
        {
        iStatusCode = KErrGeneral;
        }
    
    if( KErrNone != iStatusCode )
        {
        iNoteHandler->FinishProgressNote();    
        }
    else
        {
        TRAP_IGNORE( iUploadSession->StartTrackingProgressL( aKey ) );    
        }     
    __LOG( "[CUpnpUploadHandler] TransferStarted() end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::TransferCompleted
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::TransferCompleted( TInt aKey,
                                            TInt aStatus,
                                            const TDesC& /*aFilePath*/ )
    {
    __LOG( "[CUpnpUploadHandler] TransferCompleted()" );
    __LOG1( "[CUpnpUploadHandler] aKey %d", aKey );
    __LOG1( "[CUpnpUploadHandler] aStatus %d", aStatus );
    __LOG1( "[CUpnpUploadHandler] iTotalCount %d", iTotalCount );
        
    iStatusCode = aStatus;    
    iUploadItems++;
    
    __LOG1( "[CUpnpUploadHandler] iUploadItems %d", iUploadItems );
    
    if( KErrNone == iStatusCode && iObjectsToCopy->Count() > 0 ) 
        {
        if( iUploadMode == EUpnpMove )
            {
            __LOG( "Deleting file..." );
            TInt deleteError = BaflUtils::DeleteFile( 
                                            iCoeEnv->FsSession(),
                                            *(*iObjectsToCopy)[aKey] );
            if( deleteError != KErrNone )
            {
            __LOG( "Failed to delete file!");
            }
            }
        delete (*iObjectsToCopy)[aKey];
        (*iObjectsToCopy)[aKey] = NULL;
        iCopiedFileStillInArray = EFalse;
        // Update the download completeness percentage value
        iCopyCompleteness = KProgressBaseValue * iUploadItems;

        // Update the progress note
        iNoteHandler->SetValue( iCopyCompleteness );
        }
    
    if( KErrNone != iStatusCode || 
      ( aKey < 0 || aKey > iCopyPosition ) || 
        iTotalCount <= iUploadItems )
        {
        iNoteHandler->FinishProgressNote();    
        }
    else if( --iUploadIndex <=0 )
        {
        TRAPD( error, StartUploadL() );
        if( error != KErrNone )
            {
            iStatusCode = error;
            iNoteHandler->FinishProgressNote(); 
            }
        }
    __LOG( "[CUpnpUploadHandler] TransferCompleted() end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::TransferProgress
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::TransferProgress( TInt aKey,
                                           TInt aBytes,
                                           TInt aTotalBytes )
    {
    __LOG1( "[CUpnpUploadHandler] TransferProgress() aKey %d", aKey );
    __LOG1( "[CUpnpUploadHandler] TransferProgress() iCopyPosition %d", iCopyPosition );
    if( aKey < 0 || aKey > iCopyPosition )
        {
        iStatusCode = KErrGeneral;
        iNoteHandler->FinishProgressNote();
        }
    else
        {
        float progress = ((float)aBytes / aTotalBytes) * 100;
     
        if( aBytes == aTotalBytes )
            { 
            iCopiedFileStillInArray = ETrue;
            }
        
        iNoteHandler->SetValue( iCopyCompleteness + (TInt)progress);    
        }    
    __LOG( "[CUpnpUploadHandler] TransferProgress() -end" );
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::StartUploadL
// Starts the next upload. Leaves (KErrCompletion) if there are no more
// objects to upload.
// --------------------------------------------------------------------------
//
void CUpnpUploadHandler::StartUploadL()
    {
    __LOG( "[CUpnpUploadHandler] StartUploadL()" );
    
    TInt error = KErrNone;
     
    if( iUploadFirst )
        {
        iUploadIndex = 1;
        iUploadFirst = EFalse;
        }
    else
        {
        iUploadIndex = iTotalCount - iUploadItems;
    
        if( iUploadIndex > KUploadItemValue )
            {
            iUploadIndex = KUploadItemValue;
            }
        else if( iUploadIndex <= 0 )
            {
            //copy is fininshed
            iStatusCode = error;
            iNoteHandler->FinishProgressNote();
            return;
            }    
        }

    for( TInt i = 0; i< iUploadIndex; i++ )
        {
        iCopyPosition++;
        
        TBool isDrmProtected = ETrue;
        TRAP( error, isDrmProtected = UPnPFileUtility::IsFileProtectedL( *(*iObjectsToCopy)[ iCopyPosition ] ) );

        if( error == KErrNone && isDrmProtected == EFalse)
            {
            TRAP( error, iUploadSession->StartUploadL( 
                                    *(*iObjectsToCopy)[ iCopyPosition ],
                                    iCopyPosition ) );
            }
        
        // If parsing or sending the download action failed, exit
        if( error != KErrNone )
            {
            iUploadSession->CancelAllTransfers();  
            iStatusCode = error;
            i = iTotalCount;
            iNoteHandler->FinishProgressNote();
            } 
        else if( isDrmProtected )
            {
            __LOG( "[CUpnpUploadHandler] StartUploadL() drm file, start timer" );
            // show note only once if there is several drm protected files
            if( !iDrmFilesSkipped )
                {
                TRAP_IGNORE( iNoteHandler->ShowSkippingDRMFilesNoteL() );
                iDrmFilesSkipped = ETrue;
                }
             
            // start timer to process next file   
            Call();             
            }
        }
    __LOG( "[CUpnpUploadHandler] StartUploadL() end" );
    }





// --------------------------------------------------------------------------
// CUpnpUploadHandler::RunL
// --------------------------------------------------------------------------
void CUpnpUploadHandler::RunL()
    {
    __LOG( "CUpnpUploadHandler::RunL" );
    
    iUploadItems++;
    
    if( --iUploadIndex <=0 )
        {
        StartUploadL();
        }
    }

// --------------------------------------------------------------------------
// CUpnpUploadHandler::RunError
// --------------------------------------------------------------------------
TInt CUpnpUploadHandler::RunError( TInt aError )
    {
    __LOG1( "CUpnpUploadHandler::RunError %d", aError );
    iUploadSession->CancelAllTransfers();  
    iStatusCode = aError;
    iNoteHandler->FinishProgressNote();
    
    return KErrNone;
    }   
    
  
        
// End of file