appinstaller/AppMngr2/Sisx/src/appmngr2sisxruntime.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:05:20 +0300
changeset 25 98b66e4fb0be
parent 0 ba25891c3a9e
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* Copyright (c) 2008-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:   Native SISX runtime type for AppMngr2
*
*/


#include "appmngr2sisxruntime.h"        // CAppMngr2SisxRuntime
#include "appmngr2sisxappinfo.h"        // CAppMngr2SisxAppInfo
#include "appmngr2sisxpackageinfo.h"    // CAppMngr2SisxPackageInfo
#include "appmngr2sisxunknownlist.h"    // CAppMngr2SisxUnknownList
#include "appmngr2sisxswimonitor.h"     // CAppMngr2SisxSwiMonitor
#include <appmngr2runtimeobserver.h>    // MAppMngr2RuntimeObserver
#include <appmngr2recognizedfile.h>     // CAppMngr2RecognizedFile
#include <appmngr2cleanuputils.h>       // CleanupResetAndDestroyPushL
#include <appmngr2debugutils.h>         // FLOG macros
#include <swi/sisregistryentry.h>       // RSisRegistryEntry
#include <swi/sisregistrypackage.h>     // CSisRegistryPackage
#include <data_caging_path_literals.hrh> // KDC_APP_BITMAP_DIR
#include <AknIconArray.h>               // CAknIconArray
#include <AknsUtils.h>                  // AknsUtils
#include <gulicon.h>                    // CGulIcon
#include <eikenv.h>                     // CEikonEnv
#include <driveinfo.h>                  // DriveInfo
#include <f32file.h>                    // RFs
#include <SWInstDefs.h>                 // MIME types
#include <appmngr2sisx.mbg>             // icon IDs

_LIT( KAppMngr2SisxIconFileNameMif, "AppMngr2Sisx.mif" );
_LIT( KDriveSpec, "%c:" );
_LIT8( KSisInstallerUidType, "x-epoc/x-app268436505" );

const TInt KUidLength = 8;


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

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::NewL()
// ---------------------------------------------------------------------------
//
CAppMngr2SisxRuntime* CAppMngr2SisxRuntime::NewL( MAppMngr2RuntimeObserver &aObserver )
    {
    CAppMngr2SisxRuntime* self = new (ELeave) CAppMngr2SisxRuntime( aObserver );
    CleanupStack::PushL( self );
    self->ConstructL( aObserver );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::~CAppMngr2SisxRuntime()
// ---------------------------------------------------------------------------
//
CAppMngr2SisxRuntime::~CAppMngr2SisxRuntime()
    {
    delete iSwiMonitor;
    iSisRegistrySession.Close();
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::LoadIconsL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::LoadIconsL( CAknIconArray& aIconArray )
    {
    MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
    HBufC* iconFilePath = NULL;
    
    iconFilePath = FullBitmapFileNameLC( KAppMngr2SisxIconFileNameMif );

    // Icon loading order in must be the same in which SISX icons
    // are defined in TAppMngr2SisxIcons enum in appmngr2sisx.hrh.
    
    // Icon 0: SIS application icon, EQgnMenuAmSis
    CGulIcon* icon = AknsUtils::CreateGulIconL( skinInstance,
            KAknsIIDQgnMenuAmSis, *iconFilePath,
            EMbmAppmngr2sisxQgn_menu_am_sis,
            EMbmAppmngr2sisxQgn_menu_am_sis_mask );
    CleanupStack::PushL( icon );
    aIconArray.AppendL( icon );
    CleanupStack::Pop( icon );

    // Icon 1: DRM expired rights icon, EQgnPropDrmExpLarge
    icon = AknsUtils::CreateGulIconL( skinInstance,
            KAknsIIDQgnPropDrmRightsExpLarge, *iconFilePath,
            EMbmAppmngr2sisxQgn_prop_drm_exp_large,
            EMbmAppmngr2sisxQgn_prop_drm_exp_large_mask );
    CleanupStack::PushL( icon );
    aIconArray.AppendL( icon );
    CleanupStack::Pop( icon );                                                

    // Icon 2: untrusted SIS application, EQgnIndiAmInstNoAdd
    // Indicator icons are color-skinned as normal icons are
    // graphically-skinned. CreateColorIconL() must be used to
    // create color-skinned icon.
    CFbsBitmap* bitmap = NULL;
    CFbsBitmap* mask = NULL;
    AknsUtils::CreateColorIconLC( skinInstance,
            KAknsIIDQgnIndiAmInstNoAdd,
            KAknsIIDQsnIconColors, EAknsCIQsnIconColorsCG13,
            bitmap, mask, *iconFilePath,
            EMbmAppmngr2sisxQgn_indi_am_inst_no_add,
            EMbmAppmngr2sisxQgn_indi_am_inst_no_add_mask,
            KRgbBlack );
    icon = CGulIcon::NewL( bitmap, mask );
    icon->SetBitmapsOwnedExternally( EFalse );
    CleanupStack::Pop( 2 );   // bitmap and mask, order may vary
    CleanupStack::PushL( icon );
    aIconArray.AppendL( icon );
    CleanupStack::Pop( icon );

    CleanupStack::PopAndDestroy( iconFilePath );
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::GetSupportedDataTypesL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::GetSupportedDataTypesL(
        CDataTypeArray& aDataTypeArray )
    {
    TDataType sisxType( SwiUI::KSisxMimeType );
    aDataTypeArray.AppendL( sisxType );
    TDataType sisType( SwiUI::KSisMimeType );
    aDataTypeArray.AppendL( sisType );
    TDataType pipType( SwiUI::KPipMimeType );
    aDataTypeArray.AppendL( pipType );
    TDataType installedUidType( KSisInstallerUidType );
    aDataTypeArray.AppendL( installedUidType );
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::GetAdditionalDirsToScanL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::GetAdditionalDirsToScanL( RFs& aFsSession,
        RPointerArray<HBufC>& aDirs )
    {
    // Return KAppMngr2DaemonPrivateFolder directories that may contain
    // untrusted applications. Untrusted application is partially installed
    // and user needs to install it's SISX from KAppMngr2DaemonPrivateFolder
    // to complete it's installation. For example, when memory card is inserted
    // in mobile phone, installer processes applications installed in the memory
    // card. If some memory card application requires user-granted capabilities,
    // installer creates SISX in KAppMngr2DaemonPrivateFolder. The SISX must be
    // installed to grant the capabilities to the application.
    TDriveList driveList;
    TInt driveCount = 0;
    User::LeaveIfError( DriveInfo::GetUserVisibleDrives( aFsSession, driveList, driveCount ) );
    
    TInt driveListLength = driveList.Length();
    for( TInt driveNumber = 0; driveNumber < driveListLength; driveNumber++ )
        {
        if( driveList[ driveNumber ] )
            {
            // Internal and remote drives are not listed. Internal drives cannot
            // be removed/replaced, so there are no untrusted applications either.
            // Remote drives cannot be used to install applications at all.
            TUint driveStatus = 0;
            TInt err = DriveInfo::GetDriveStatus( aFsSession, driveNumber, driveStatus );
            if( err == KErrNone && !( driveStatus & DriveInfo::EDriveRemote ) &&
                    !( driveStatus & DriveInfo::EDriveInternal ) )
                {
                TChar driveLetter;
                if( RFs::DriveToChar( driveNumber, driveLetter ) == KErrNone )
                    {
                    const TInt dirLength = KDriveSpec().Length() +
                            KAppMngr2DaemonPrivateFolder().Length(); 
                    HBufC* dir = HBufC::NewLC( dirLength );
                    TPtr dirPtr = dir->Des();
                    dirPtr.Format( KDriveSpec, static_cast<TUint>( driveLetter ) );
                    dirPtr.Append( KAppMngr2DaemonPrivateFolder );
                    aDirs.AppendL( dir );
                    FLOG( "CAppMngr2SisxRuntime::GetAdditionalDirsToScanL: adding %S", dir );
                    CleanupStack::Pop( dir );
                    }
                }
            }
        }
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::GetInstallationFilesL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::GetInstallationFilesL(
        RPointerArray<CAppMngr2PackageInfo>& aPackageInfos,
        const RPointerArray<CAppMngr2RecognizedFile>& aFileList,
        RFs& aFsSession, TRequestStatus& aStatus )
    {
    TInt fileCount = aFileList.Count();
    FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: fileCount = %d", fileCount );
    if( fileCount )
        {
        // Check if this is the memory card installer daemon private folder.
        // All files are from the same directory, 
        CAppMngr2RecognizedFile* firstFile = aFileList[ 0 ];
        if( firstFile->FileName().Find( KAppMngr2DaemonPrivateFolder ) == KErrNotFound )
            {
            // No, it isn't. Process all files in aFileList and create package info objects.
            FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: normal folder" );
            for( TInt index = 0; index < fileCount; index++ )
                {
                CAppMngr2RecognizedFile* file = aFileList[ index ];
                
                TPtrC fileName = file->FileName();
                FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: file %S", &fileName );
                CreateNewPackageL( fileName, aPackageInfos, aFsSession );
                }
            }
        else
            {
            // It is. Process only those files that are not installed.
            FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: swidaemon private folder" );
            RArray<TUid> uids;
            CleanupClosePushL( uids );
            iSisRegistrySession.InstalledUidsL( uids );
            
            for( TInt index = 0; index < fileCount; index++ )
                {
                CAppMngr2RecognizedFile* recFile = aFileList[ index ];
                
                TPtrC fileName = recFile->FileName();
                FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: file %S", &fileName );
                
                // extract UID name from full path name
                TParsePtrC parse( fileName );
                TPtrC uidName = parse.Name().Left( KUidLength );
                FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: uidName %S", &uidName );
                
                // convert UID name to numerical form
                TLex lex( uidName );
                TUint32 uidValue;
                TInt lexError = lex.Val( uidValue, EHex );
                if( lexError == KErrNone )
                    {
                    // It's an UID name, try to display package name instead
                    FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: value %08x", uidValue );
                    
                    // check if this UID is already installed
                    TUid fileUid;
                    fileUid.iUid = uidValue;
                    if( uids.Find( fileUid ) == KErrNotFound )
                        {
                        FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: not installed" );
                        // Not installed, must be displayed. 
                        CreateNewPackageL( fileName, aPackageInfos, aFsSession );
                        }
                    else
                        {
                        FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: is installed" );
                        // Installed, two possible cases here. The package is in the
                        // SWI daemon private folder in memory card because:
                        // 1) memory card application is installed in use normally, or
                        // 2) the same application is already in ROM/internal drive.
                        // In case 1) this item MAY NOT be displayed here as it is already
                        // displayed in "Installed apps" side. In case of 2) it MUST be
                        // displayed, so that user can remove it from memory card. Cases
                        // 1) and 2) can be identified by checking the memory card's
                        // "unknown" list. If the sis package is unknown, it is case 2),
                        // as applications that are installed in use, are always known.
                        TChar driveLetter = parse.Drive()[ 0 ];
                        TInt driveNumber = 0;
                        User::LeaveIfError( RFs::CharToDrive( driveLetter, driveNumber ) );
                        CAppMngr2SisxUnknownList* unknownSisx = CAppMngr2SisxUnknownList::NewLC(
                                driveNumber );
                        TInt unknownIndex = unknownSisx->FindPkgWithUID( fileUid );
                        FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: unknownIndex %d",
                                unknownIndex );
                        if( unknownIndex >= 0 && unknownIndex < unknownSisx->PkgCount() )
                            {
                            // It is unknown package after all, add it to the list.
                            CreateNewPackageL( fileName, aPackageInfos, aFsSession );
                            }
                        CleanupStack::PopAndDestroy( unknownSisx );
                        }
                    }
                else
                    {
                    // Not an UID name, must be displayed.
                    FLOG( "CAppMngr2SisxRuntime::GetInstallationFilesL: not UID name (lexErr %d)",
                            lexError );
                    CreateNewPackageL( fileName, aPackageInfos, aFsSession );
                    }
                }

            CleanupStack::PopAndDestroy( &uids );
            }
        }
    TRequestStatus* status = &aStatus;
    User::RequestComplete( status, KErrNone );
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::CancelGetInstallationFiles()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::CancelGetInstallationFiles()
    {
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::GetInstalledAppsL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::GetInstalledAppsL(
        RPointerArray<CAppMngr2AppInfo>& aApps,
        RFs& aFsSession, TRequestStatus& aStatus )
    {
    FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL" );

    RPointerArray<Swi::CSisRegistryPackage> removablePackages;
    CleanupResetAndDestroyPushL( removablePackages );
    iSisRegistrySession.RemovablePackagesL( removablePackages );

    TInt appCount = removablePackages.Count();
    FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL, appCount %d", appCount );
    for( TInt index = 0; index < appCount; index++ )
        {
        Swi::RSisRegistryEntry entry;
        CleanupClosePushL( entry );
        FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL, uid 0x%08x, name %S",
                removablePackages[ index ]->Uid().Uid,
                &( removablePackages[ index ]->Name() ) );
        entry.OpenL( iSisRegistrySession, *( removablePackages[ index ] ) );

        FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL, IsPresentL = %d",
                entry.IsPresentL() );        
        // Check that sis entry is present. We should not show applications 
        // installed to memory card if card is not found.        
        if ( entry.IsPresentL() )
            {
            FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL, Sis is present." );
            	
            CAppMngr2SisxAppInfo* appObj = NULL;
            TRAPD( err, appObj = CAppMngr2SisxAppInfo::NewL( *this, entry, aFsSession ) );
            FLOG( "CAppMngr2SisxRuntime::GetInstalledAppsL, err %d", err );
            if( err == KErrNone )
                {
                CleanupStack::PushL( appObj );
                aApps.AppendL( appObj );
                CleanupStack::Pop( appObj );
                }
            }
            
        CleanupStack::PopAndDestroy( &entry );
        }

    CleanupStack::PopAndDestroy( &removablePackages );

    TRequestStatus* status = &aStatus;
    User::RequestComplete( status, KErrNone );
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::CancelGetInstalledApps()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::CancelGetInstalledApps()
    {
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::CAppMngr2SisxRuntime()
// ---------------------------------------------------------------------------
//
CAppMngr2SisxRuntime::CAppMngr2SisxRuntime( MAppMngr2RuntimeObserver &aObserver )
        : CAppMngr2Runtime( aObserver ) 
    {
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::ConstructL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::ConstructL( MAppMngr2RuntimeObserver& aObserver )
    {
    User::LeaveIfError( iSisRegistrySession.Connect() );
    iSwiMonitor = CAppMngr2SisxSwiMonitor::NewL( aObserver );
    }

// ---------------------------------------------------------------------------
// CAppMngr2SisxRuntime::ConstructL()
// ---------------------------------------------------------------------------
//
void CAppMngr2SisxRuntime::CreateNewPackageL( const TDesC& aFileName,
        RPointerArray<CAppMngr2PackageInfo>& aPackageInfos, RFs& aFs )
    {
    CAppMngr2SisxPackageInfo* packageInfo = NULL;
    TRAPD( err, packageInfo = CAppMngr2SisxPackageInfo::NewL( *this, aFileName, aFs ) );
    FLOG( "CAppMngr2SisxRuntime::CreateNewPackageL: file %S, err %d", &aFileName, err );
    if( err == KErrNone )
        {
        CleanupStack::PushL( packageInfo );
        aPackageInfos.AppendL( packageInfo );
        CleanupStack::Pop( packageInfo );
        }
    }