connectivitymodules/SeCon/services/pcd/src/sconinstaller.cpp
author hgs
Tue, 12 Oct 2010 17:42:13 +0530
changeset 64 a62b67d1f67c
parent 40 b63e67867dcd
permissions -rw-r--r--
201041

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


// INCLUDE FILES
#include <s32mem.h> // For RBufWriteStream
#include <utf.h>  // for CnvUtfConverter
#include <usif/usifcommon.h>
#include <usif/scr/scr.h>
#include <driveinfo.h>

using namespace Usif;

#include "debug.h"
#include "sconinstaller.h"
#include "sconpcdconsts.h"

const TInt KSConSeConUidValue = 0x101f99f6;
const TUid KSConSeConUid = {KSConSeConUidValue};

_LIT8(KValSep, "=");
_LIT8(KComma, ",");
_LIT8(KLineEnd, "\r\n");

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

CSConAppInstaller* CSConAppInstaller::NewL( CSConInstallerQueue* aQueue, RFs& aFs )
    {
    CSConAppInstaller* self = new (ELeave) CSConAppInstaller( aQueue, aFs );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }
// -----------------------------------------------------------------------------
// CSConAppInstaller::CSConAppInstaller( CSConInstallerQueue* aQueue )
// Constructor
// -----------------------------------------------------------------------------
//
CSConAppInstaller::CSConAppInstaller( CSConInstallerQueue* aQueue, RFs& aFs ) :
    CActive( EPriorityStandard ), iQueue( aQueue ), iFs( aFs )
    {
    CActiveScheduler::Add( this );
    }

void CSConAppInstaller::ConstructL()
    {
    iSifOptions = COpaqueNamedParams::NewL();
    iSifResults = COpaqueNamedParams::NewL();
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::~CSConAppInstaller()
// Destructor
// -----------------------------------------------------------------------------
//
CSConAppInstaller::~CSConAppInstaller()
    {
    TRACE_FUNC;
    Cancel();
    iSwInstaller.Close();
    delete iSifOptions;
    delete iSifResults;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::StartInstaller( TInt& aTaskId )
// Starts the installer task
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::StartInstaller( TInt& aTaskId )
    {
    TRACE_FUNC_ENTRY;
    CSConTask* task = NULL;
    TRequestStatus* status = NULL;
    TInt err( KErrNone );
    
    TInt ret = iQueue->GetTask( aTaskId, task );
    
    if( aTaskId > 0 && ret != KErrNotFound )
        {
        if ( IsActive() )
            {
            LOGGER_WRITE("WARNING! SConAppInstaller was not on idle state!");
            iQueue->CompleteTask( aTaskId, KErrInUse );
            TRACE_FUNC_EXIT;
            return;
            }
        
        
        iCurrentTask = aTaskId;
        iQueue->SetTaskProgress( aTaskId, KSConCodeProcessingStarted );
        
        switch( task->GetServiceId() )
            {
            case EInstall :
                iQueue->ChangeQueueProcessStatus();
                err = iSwInstaller.Connect();
                if( err == KErrNone )
                    {
                    TRAP(err, ProcessInstallL( *task->iInstallParams ));
                    if( err != KErrNone )
                        {
                        LOGGER_WRITE_1( "StartInstaller ProcessInstallL err: %d", err );
                        iStatus = KRequestPending;
                        SetActive();
                        status = &iStatus;
                        User::RequestComplete( status, err );
                        }
                    }
                
                break;
            case EUninstall :
                iQueue->ChangeQueueProcessStatus();
                err = iSwInstaller.Connect();
                if( err == KErrNone )
                    {
                    LOGGER_WRITE( "Begin to uninstall.. " );
                    
                    TRAP( err, ProcessUninstallL( *task->iUninstallParams ) );
                    if( err != KErrNone )
                        {
                        LOGGER_WRITE_1( "StartInstaller ProcessUninstallL err: %d", err );
                        iStatus = KRequestPending;
                        SetActive();
                        status = &iStatus;
                        User::RequestComplete( status, err );
                        }
                    }
                
                break;
            case EListInstalledApps :
                iQueue->ChangeQueueProcessStatus();
                iStatus = KRequestPending;
                SetActive();
                TRAP( err, ProcessListInstalledAppsL() );
                status = &iStatus;
                User::RequestComplete( status, err );
                break;
            default :
                break;
            }
        }
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::StopInstaller( TInt& aTaskId )
// Stops the installer task
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::StopInstaller( TInt& aTaskId )
    {
    TRACE_FUNC_ENTRY;
    //If the task is the current task, cancel it first
    if( iCurrentTask == aTaskId )
        {
        Cancel();
        iSwInstaller.Close();
        }
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// TBool CSConAppInstaller::InstallerActive()
// returns installer activity status
// -----------------------------------------------------------------------------
//
TBool CSConAppInstaller::InstallerActive() const
    {
    return IsActive();
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::DoCancel()
// Implementation of CActive::DoCancel()
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::DoCancel()
    {
    TRACE_FUNC_ENTRY;
    LOGGER_WRITE("Cancel iSwInstaller");
    iSwInstaller.CancelOperation();
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::RunL()
// Implementation of CActive::RunL()
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::RunL()
    {
    TRACE_FUNC_ENTRY;
    iSwInstaller.Close();
    iQueue->ChangeQueueProcessStatus();
    TInt err( iStatus.Int() );
    LOGGER_WRITE_1( "CSConAppInstaller::RunL() iStatus.Int() : returned %d", err );
    
    CSConTask* task = NULL;
    TInt taskErr = iQueue->GetTask( iCurrentTask, task );
    if( taskErr == KErrNone )
        {
        if ( task->GetServiceId() == EInstall || task->GetServiceId() == EUninstall )
            {
            TRAPD(dataErr, WriteTaskDataL( *task ));
            if (dataErr)
                {
                LOGGER_WRITE_1("WriteTaskDataL err: %d", dataErr);
                }
            }
        
        if( task->GetServiceId() == EInstall && err == KErrNone )
            {
            LOGGER_WRITE( "CSConAppInstaller::RunL() : before DeleteFile" );
            //delete sis after succesfull install
            iFs.Delete( task->iInstallParams->iPath );
            }
        }
    
    iQueue->CompleteTask( iCurrentTask, err );
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::WriteTaskDataL()
// Writes data to task
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::WriteTaskDataL( CSConTask& aTask )
    {
    TRACE_FUNC_ENTRY;
    CBufFlat* buffer = CBufFlat::NewL(200);
    CleanupStack::PushL(buffer);
    RBufWriteStream stream( *buffer );
    CleanupClosePushL( stream );
    
    ExternalizeResultArrayIntValL( KSifOutParam_ComponentId , stream);
    ExternalizeResultIntValL( KSifOutParam_ErrCategory , stream);
    ExternalizeResultIntValL( KSifOutParam_ErrCode , stream);
    //ExternalizeResultIntValL( KSifOutParam_ExtendedErrCode , stream);
    ExternalizeResultStringValL( KSifOutParam_ErrMessage , stream);
    ExternalizeResultStringValL( KSifOutParam_ErrMessageDetails , stream);
    
    stream.CommitL();
    
    buffer->Compress();
    
    HBufC8* data = HBufC8::NewL( buffer->Size() );
    TPtr8 dataPtr = data->Des();
    buffer->Read( 0, dataPtr, buffer->Size() );
    
    if ( aTask.GetServiceId() == EInstall )
        {
        if ( aTask.iInstallParams->iData )
            {
            delete aTask.iInstallParams->iData;
            aTask.iInstallParams->iData = NULL;
            }
        aTask.iInstallParams->iData = data;
        data = NULL;
        }
    else if ( aTask.GetServiceId() == EUninstall )
        {
        if ( aTask.iUninstallParams->iData )
            {
            delete aTask.iUninstallParams->iData;
            aTask.iUninstallParams->iData = NULL;
            }
        aTask.iUninstallParams->iData = data;
        data = NULL;
        }
    else
        {
        delete data;
        data = NULL;
        }
    
    CleanupStack::PopAndDestroy( &stream );
    CleanupStack::PopAndDestroy( buffer );
    TRACE_FUNC_EXIT;
    }

void CSConAppInstaller::ExternalizeResultArrayIntValL( const TDesC& aName, RWriteStream& aStream )
    {
    TRACE_FUNC_ENTRY;
    RArray<TInt> valueArray;
    TRAPD(err, valueArray = iSifResults->IntArrayByNameL(aName));
    if ( !err && valueArray.Count() > 0 )
        {
        LOGGER_WRITE_1("count: %d", valueArray.Count());
        TBuf8<100> nameBuf;
        err = CnvUtfConverter::ConvertFromUnicodeToUtf8( nameBuf, aName );
        if (!err)
            {
            LOGGER_WRITE("2");
            aStream.WriteL( nameBuf, nameBuf.Length() );
            aStream.WriteL( KValSep, 1 );
            aStream.WriteInt32L( valueArray[0] );
            for (TInt i=1; i<valueArray.Count(); i++)
                {
                aStream.WriteL( KComma, 1 );
                aStream.WriteInt32L( valueArray[i] );
                }
            aStream.WriteL( KLineEnd, 2 );
            }
        }
    TRACE_FUNC_EXIT;
    }
// -----------------------------------------------------------------------------
// CSConAppInstaller::ExternalizeResultIntValL()
// Read integer value and write it to stream
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::ExternalizeResultIntValL( const TDesC& aName, RWriteStream& aStream )
    {
    TRACE_FUNC_ENTRY;
    TInt value;
    TBool found(EFalse);
    found = iSifResults->GetIntByNameL(aName, value);

    if (found)
        {
        TBuf8<100> nameBuf;
        TInt err = CnvUtfConverter::ConvertFromUnicodeToUtf8( nameBuf, aName );
        if (!err)
            {
            aStream.WriteL( nameBuf, nameBuf.Length() );
            aStream.WriteL( KValSep, 1 );
            aStream.WriteInt32L( value );
            aStream.WriteL( KLineEnd, 2 );
            }
        }
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::ExternalizeResultStringValL()
// Read string value and write it to stream
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::ExternalizeResultStringValL( const TDesC& aName, RWriteStream& aStream )
    {
    TRACE_FUNC_ENTRY;
    const TDesC& strValue = iSifResults->StringByNameL( aName );
    if (strValue.Length() > 0)
        {
        TBuf8<100> nameBuf;
        TInt err = CnvUtfConverter::ConvertFromUnicodeToUtf8( nameBuf, aName );
        if (!err)
            {
            HBufC8* nameVal = CnvUtfConverter::ConvertFromUnicodeToUtf8L( strValue );
            CleanupStack::PushL( nameVal );
            aStream.WriteL( nameBuf, nameBuf.Length() );
            aStream.WriteL( KValSep, 1 );
            aStream.WriteL( nameVal->Des(), nameVal->Length() );
            aStream.WriteL( KLineEnd, 2 );
            CleanupStack::PopAndDestroy( nameVal );
            }
        }
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::ProcessInstallL()
// Executes Install task
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::ProcessInstallL( const CSConInstall& aInstallParams )
    {
    TRACE_FUNC_ENTRY;
    iSifOptions->Cleanup();
    iSifResults->Cleanup();
    
    if ( aInstallParams.iMode == ESilentInstall )
        {
        LOGGER_WRITE( "Begin silent installation.. " );
        
        iSifOptions->AddIntL( Usif::KSifInParam_InstallSilently, ETrue );
        iSifOptions->AddIntL( Usif::KSifInParam_PerformOCSP, Usif::ENotAllowed );   
        // Note if upgrade is allowed, see NeedsInstallingL function.
        iSifOptions->AddIntL( Usif::KSifInParam_AllowUpgrade, Usif::EAllowed );
        iSifOptions->AddIntL( Usif::KSifInParam_AllowUntrusted, Usif::ENotAllowed );
        iSifOptions->AddIntL( Usif::KSifInParam_GrantCapabilities, Usif::ENotAllowed ); 
        // Defined for the install.
        iSifOptions->AddIntL( Usif::KSifInParam_InstallOptionalItems, Usif::EAllowed );          
        iSifOptions->AddIntL( Usif::KSifInParam_IgnoreOCSPWarnings, Usif::EAllowed );            
        iSifOptions->AddIntL( Usif::KSifInParam_AllowAppShutdown, Usif::EAllowed );
        iSifOptions->AddIntL( Usif::KSifInParam_AllowDownload, Usif::EAllowed );
        iSifOptions->AddIntL( Usif::KSifInParam_AllowOverwrite, Usif::EAllowed );

        iSwInstaller.Install( aInstallParams.iPath, *iSifOptions,
                *iSifResults, iStatus, ETrue );
        }
    else
        {
        LOGGER_WRITE( "Begin to install.. " );
        
        iSwInstaller.Install( aInstallParams.iPath, *iSifOptions,
                *iSifResults, iStatus, ETrue );
        }
    SetActive();
    TRACE_FUNC_EXIT;
    }

// -----------------------------------------------------------------------------
// CSConAppInstaller::ProcessUninstallL( const CSConUninstall& aUninstallParams )
// Executes UnInstall task
// -----------------------------------------------------------------------------
//
void CSConAppInstaller::ProcessUninstallL( const CSConUninstall& aUninstallParams )
    {
    TRACE_FUNC_ENTRY;
    LOGGER_WRITE_1( "aUid: 0x%08x", aUninstallParams.iUid.iUid );
    LOGGER_WRITE_1( "aName: %S", &aUninstallParams.iName );
    LOGGER_WRITE_1( "aVendor: %S", &aUninstallParams.iVendor );
    LOGGER_WRITE_1( "aType: %d", aUninstallParams.iType );
    LOGGER_WRITE_1( "aMode: %d", aUninstallParams.iMode );
    
    if ( aUninstallParams.iUid == KSConSeConUid )
	    {
	    LOGGER_WRITE("Cannot uninstall itself, leave");
	    // cannot uninstall itself
	    User::Leave( KErrInUse ); //SwiUI::KSWInstErrFileInUse );
	    }
    TComponentId componentId = aUninstallParams.iUid.iUid;
    iSifOptions->Cleanup();
    iSifResults->Cleanup();
    
    if ( aUninstallParams.iMode == ESilentInstall)
        {
        iSifOptions->AddIntL( Usif::KSifInParam_InstallSilently, ETrue );
        iSwInstaller.Uninstall( componentId, *iSifOptions, *iSifResults, iStatus, ETrue );
        }
    else
        {
        iSwInstaller.Uninstall( componentId, *iSifOptions, *iSifResults, iStatus, ETrue );
        }
    SetActive();
    TRACE_FUNC_EXIT;
    }
    
//--------------------------------------------------------------------------------
//void CSConAppInstaller::ProcessListInstalledAppsL()
//--------------------------------------------------------------------------------
//
void CSConAppInstaller::ProcessListInstalledAppsL()
    {
    TRACE_FUNC_ENTRY;
    
    CSConTask* task = NULL;
    User::LeaveIfError( iQueue->GetTask( iCurrentTask, task ) );
    
    CSConListInstApps& listInstApps = *task->iListAppsParams;
    Usif::RSoftwareComponentRegistry scr;
    User::LeaveIfError( scr.Connect() );
    CleanupClosePushL( scr );
    
    RArray<Usif::TComponentId> componentList;
    CleanupClosePushL( componentList );
    Usif::CComponentFilter* filter = Usif::CComponentFilter::NewLC();
    
    if ( listInstApps.iAllApps )
        {
        TDriveList driveList;
        // Get all drives that are visible to the user.
        TInt driveCount;
        User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveList, driveCount ) );
        filter->SetInstalledDrivesL( driveList );
        }
    else
        {
        filter->SetInstalledDrivesL( listInstApps.iDriveList );
        }
            
    scr.GetComponentIdsL( componentList, filter);
    
    CleanupStack::PopAndDestroy( filter );
    LOGGER_WRITE_1("components found: %d", componentList.Count());
    for (int i=0; i<componentList.Count(); i++)
        {
        Usif::CComponentEntry* entry = Usif::CComponentEntry::NewLC();
        TBool found = scr.GetComponentL(componentList[i], *entry );
        if (!found)
            User::Leave(KErrNotFound);
        
        CSConInstApp* app = new (ELeave) CSConInstApp();
        CleanupStack::PushL( app );
        
        StrCopyL( entry->Name(), app->iName );
        StrCopyL( entry->Vendor(), app->iVendor );
        app->iSize = entry->ComponentSize();
        StrCopyL( entry->Version(), app->iVersion );
        app->iWidgetBundleId = entry->GlobalId().AllocL();
        
        app->iUid.iUid = componentList[i];
        
        if ( entry->SoftwareType().Match( Usif::KSoftwareTypeNative ) == 0 )
            {
            app->iType = ESisApplication;
            }
        else if ( entry->SoftwareType().Match( Usif::KSoftwareTypeJava ) == 0 )
            {
            app->iType = EJavaApplication;
            }
        else if ( entry->SoftwareType().Match( Usif::KSoftwareTypeWidget ) == 0 )
            {
            app->iType = EWidgetApplication;
            }
        
        User::LeaveIfError( listInstApps.iApps.Append( app ) );
        CleanupStack::Pop( app );
            
        CleanupStack::PopAndDestroy( entry );
        }
    CleanupStack::PopAndDestroy( &componentList );
    CleanupStack::PopAndDestroy( &scr );
    
    TRACE_FUNC_EXIT;
    }

void CSConAppInstaller::StrCopyL( const TDesC& aSrc, TDes& aDest )
    {
    if (aSrc.Size() > aDest.MaxSize())
        User::Leave(KErrTooBig);
    aDest.Copy( aSrc );
    }
// End of file