connectivitymodules/SeCon/services/pcd/src/sconqueue.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:56 +0100
branchRCL_3
changeset 20 4a793f564d72
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201032 Kit: 201035

/*
* Copyright (c) 2005-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:  Queue implementation
*
*/


// INCLUDE FILES

#include "sconqueue.h"
#include "sconpcdconsts.h"
#include "debug.h"
#include <SWInstDefs.h> // installer errors

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


// -----------------------------------------------------------------------------
// CSConTaskQueue::~CSConTaskQueue()
// Destructor
// -----------------------------------------------------------------------------
//
CSConTaskQueue::~CSConTaskQueue()
    {
    TRACE_FUNC;
    iQueue.ResetAndDestroy();
    iQueue.Close(); 
    iTimer.Close();
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::GetQueueStatus( TInt aTask, TBool aAllTasks, 
//                                  CSConStatusReply*& aStatus )
// Returns the status of a specified task / all tasks
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::GetQueueStatusL( TInt aTask, TBool aAllTasks, 
                                    CSConStatusReply*& aStatus )
    {
    RArray<TInt> completedTasks;
    CleanupClosePushL( completedTasks );
    if ( aAllTasks )
        {
        //if there are tasks
        if ( iQueue.Count() > 0 )
            {
            //set iNoTasks as EFalse
            aStatus->iNoTasks = EFalse;
            for ( TInt i = 0; i < iQueue.Count(); i++ )
                {
                //Fill reply object
                CSConTaskReply* taskReply = new (ELeave) CSConTaskReply();
                CleanupStack::PushL( taskReply );
                taskReply->InitializeL( *iQueue[i] );
                User::LeaveIfError( aStatus->iTasks.Append( taskReply ) );
                CleanupStack::Pop( taskReply );
                TBool complete = iQueue[i]->GetComplete();

                //Collect completed task numbers to array for deleting
                if ( complete )
                    {
                    completedTasks.Append( iQueue[i]->iTaskId );
                    }
                //Otherwise clean all unneccessary data from the reply packet
                else
                    {
                    taskReply->CleanTaskData(); 
                    }
                }
            }
        else
            {
            //no task in the queue
            aStatus->iNoTasks = ETrue;
            }

        //Remove completed tasks from queue
        for ( TInt j = 0; j < completedTasks.Count(); j++ )
            {
            RemoveTask( completedTasks[j] );
            }
        }
    else if ( aTask > 0 )
        {
        CSConTask* temp = new (ELeave) CSConTask();
        temp->iTaskId = aTask;
        TInt index = iQueue.Find( temp, CSConTaskQueue::Match );
        delete temp;
        
        TBool complete = EFalse;
        CSConTaskReply* taskReply(NULL);

        if ( index != KErrNotFound )
            {
            aStatus->iNoTasks = EFalse;
            //Fill reply object
            taskReply = new (ELeave) CSConTaskReply();
            CleanupStack::PushL( taskReply );
            taskReply->InitializeL( *iQueue[index] );
            User::LeaveIfError( aStatus->iTasks.Append( taskReply ) );
            CleanupStack::Pop( taskReply );
            complete = iQueue[index]->GetComplete();
            }
        else
            {
            //no task in the queue
            aStatus->iNoTasks = ETrue;
            }        
        
        //Delete completed tasks from queue
        if ( complete )
            {
            RemoveTask( aTask );
            }
        //Otherwise clean all unneccessary data from the reply packet
        else if ( taskReply )
            {
            taskReply->CleanTaskData(); 
            }
        }
    else
        {
        //no task in the queue
        aStatus->iNoTasks = ETrue;
        }
    CleanupStack::PopAndDestroy( &completedTasks ); // close
    }   
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::AddNewTask( CSConTask*& aNewTask, TInt aTaskId )
// Adds a new task to queue
// -----------------------------------------------------------------------------
//
TInt CSConTaskQueue::AddNewTask( CSConTask*& aNewTask, TInt aTaskId )
    {
    TInt ret( KErrNone );
    
    aNewTask->iTaskId = aTaskId;
    
    //Set progress value "task accepted for execution"
    aNewTask->SetProgressValue( KSConCodeTaskCreated );
    aNewTask->SetCompleteValue( EFalse );
    
    if ( iQueue.Count() == 0 )
        {
        StartQueue();
        }
    ret = iQueue.InsertInOrder( aNewTask, CSConTaskQueue::Compare );
    return ret;
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::CompleteTask( TInt aTask, TInt aError )
// Set the task to completed -mode
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::CompleteTask( TInt aTask, TInt aError )
    {
    LOGGER_WRITE_1( "CSConTaskQueue::CompleteTask aError: %d", aError );
    TInt index( KErrNotFound );
    
    CSConTask* temp = new CSConTask();
    temp->iTaskId = aTask;
    index = iQueue.Find( temp, CSConTaskQueue::Match );
    delete temp;
    
    if ( index != KErrNotFound )
        {
        TBool complete( ETrue );
        TBool notComplete( EFalse );
        TInt progress( KSConCodeTaskCompleted );        
        
        switch( aError )
            {
            case KErrNone :
                iQueue[index]->SetCompleteValue( complete );
                progress =  KSConCodeTaskCompleted;
                break;
            case KErrNotFound :
                iQueue[index]->SetCompleteValue( complete );
                progress =  KSConCodeNotFound;
                break;
            case KErrCompletion :
                iQueue[index]->SetCompleteValue( notComplete );
                progress = KSConCodeTaskPartiallyCompleted;
                break;

            // installer specific errors
            case SwiUI::KSWInstErrUserCancel:
            	LOGGER_WRITE("User cancelled the operation");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrUserCancel;
            	break;
            case SwiUI::KSWInstErrFileCorrupted:
            	LOGGER_WRITE("File is corrupted");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrFileCorrupted;
            	break;
            case SwiUI::KSWInstErrInsufficientMemory:
            	LOGGER_WRITE("Insufficient free memory in the drive to perform the operation");
	            iQueue[index]->SetCompleteValue( complete );
	            progress = KSConCodeInstErrInsufficientMemory;	
	            break;
            case SwiUI::KSWInstErrPackageNotSupported:
            	LOGGER_WRITE("Installation of the package is not supported");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrPackageNotSupported;
            	break;
            case SwiUI::KSWInstErrSecurityFailure:
            	LOGGER_WRITE("Package cannot be installed due to security error");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrSecurityFailure;
            	break;
            case SwiUI::KSWInstErrMissingDependency:
            	LOGGER_WRITE("Package cannot be installed due to missing dependency");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrMissingDependency;
            	break;
            case SwiUI::KSWInstErrFileInUse:
            	LOGGER_WRITE("Mandatory file is in use and prevents the operation");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrFileInUse;
            	break;
            case SwiUI::KSWInstErrGeneralError:
            	LOGGER_WRITE("Unknown error");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrGeneralError;
            	break;
            case SwiUI::KSWInstErrNoRights:
            	LOGGER_WRITE("The package has no rights to perform the operation");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrNoRights;
            	break;
            case SwiUI::KSWInstErrNetworkFailure:
            	LOGGER_WRITE("Indicates that network failure aborted the operation");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrNetworkFailure;
            	break;
            case SwiUI::KSWInstErrBusy:
            	LOGGER_WRITE("Installer is busy doing some other operation");
            	iQueue[index]->SetCompleteValue( complete );
        		progress = KSConCodeInstErrBusy;
            	break;
            case SwiUI::KSWInstErrAccessDenied:
            	LOGGER_WRITE("Target location of package is not accessible");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstErrAccessDenied;
            	break;
            case SwiUI::KSWInstUpgradeError:
            	LOGGER_WRITE("The package is an invalid upgrade");
            	iQueue[index]->SetCompleteValue( complete );
            	progress = KSConCodeInstUpgradeError;
            	break;
            
            default :
                iQueue[index]->SetCompleteValue( complete );
                if ( aError < KErrNone && aError >= KErrCorruptSurrogateFound )
                    {
                    // aError is always negative
                    //  -> returned errorcode is from KSConCodeFirstSymbianErr...n
                    progress = KSConCodeFirstSymbianErr - aError;
                    }
                else
                    {
                    progress = KSConCodeConflict;
                    }
                
                break;
            }
            
        iQueue[index]->SetProgressValue( progress );
        }
    StartQueue();
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::SetTaskProgress( TInt aTask, TInt aProgressValue )
// Set the task progress value
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::SetTaskProgress( TInt aTask, TInt aProgressValue )
    {
    TInt index( KErrNotFound );

    CSConTask* temp = new CSConTask();
    temp->iTaskId = aTask;
    index = iQueue.Find( temp, CSConTaskQueue::Match );
    delete temp;
    
    if ( index != KErrNotFound )
        {
        iQueue[index]->SetProgressValue( aProgressValue );
        }
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::GetTask( TInt aTaskId, CSConTask*& aTask )
// Receives a specified task
// -----------------------------------------------------------------------------
//
TInt CSConTaskQueue::GetTask( TInt aTaskId, CSConTask*& aTask )
    {
    TInt ret( KErrNone );
    TInt index;
    
    CSConTask* temp = new CSConTask();
    temp->iTaskId = aTaskId;
    index = iQueue.Find( temp, CSConTaskQueue::Match );
    delete temp;

    if ( index != KErrNotFound )
        {
        aTask = iQueue[index];
        }
    else
        {
        ret = KErrNotFound;
        }
    return ret;
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::RemoveTask( TInt aTask )
// Removes a task from the queue
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::RemoveTask( TInt aTask )
    {
    TInt index( KErrNotFound );
    
    CSConTask* temp = new CSConTask();
    temp->iTaskId = aTask;
    index = iQueue.Find( temp, CSConTaskQueue::Match );
    delete temp;
    
    if ( index != KErrNotFound ) 
        {
        delete iQueue[index];
        iQueue.Remove( index );
        iQueue.Compress();
        }
    
    if ( iQueue.Count() == 0 )
        {
        StopQueue();
        iQueue.Reset();
        }
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::CancelTask( TInt aTask, TBool aAllTasks )
// Cancels a task
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::CancelTask( TInt aTask, TBool aAllTasks )
    {
    TRACE_FUNC_ENTRY;
    
    //Remove the task from the queue
    if ( aTask > 0 && !aAllTasks )
        {
        RemoveTask( aTask );
        }
        
    //Remove all tasks from the queue
    if ( aAllTasks )
        {
        iQueue.ResetAndDestroy();
        }
    
    TRACE_FUNC_EXIT;
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::QueueProcessActive()
// The status of the process
// -----------------------------------------------------------------------------
//  
TBool CSConTaskQueue::QueueProcessActive() const
    {
    return iQueueProcessActive;
    }

// -----------------------------------------------------------------------------
// CSConTaskQueue::ChangeQueueProcessStatus()
// Changes the status of the queue process
// -----------------------------------------------------------------------------
//  
void CSConTaskQueue::ChangeQueueProcessStatus()
    {
    iQueueProcessActive = !iQueueProcessActive;
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::Reset()
// Resets the queue
// -----------------------------------------------------------------------------
//
void CSConTaskQueue::Reset()
    {
    TRACE_FUNC_ENTRY;
    iTimer.Cancel();
    iQueue.ResetAndDestroy();
    TRACE_FUNC_EXIT;
    }

// ---------------------------------------------------------
// CSConTaskQueue::Compare( const CSConTask& aFirst, 
//                          const CSConTask& aSecond )
// Compares task numbers
// ---------------------------------------------------------    
TInt CSConTaskQueue::Compare( const CSConTask& aFirst, 
                            const CSConTask& aSecond )
    {
    if ( aFirst.iTaskId < aSecond.iTaskId )
        {
        return -1;
        }
    else if ( aFirst.iTaskId > aSecond.iTaskId )
        {
        return 1;
        }
    
    return 0;
    }
    
// -----------------------------------------------------------------------------
// CSConTaskQueue::Match( const CSConTask& aFirst, const CSConTask& aSecond )
// Matches the task numbers
// -----------------------------------------------------------------------------
//
TInt CSConTaskQueue::Match( const CSConTask& aFirst, const CSConTask& aSecond )
    {
    if ( aFirst.iTaskId == aSecond.iTaskId )
        {
        return ETrue;
        }
        
    return EFalse;
    }
// End of file