filemanager/aiwprovider/src/filemanageraiwprovider.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:09:41 +0200
changeset 0 6a9f87576119
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 2008 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:  This class offers AIW services
*
*/


#include <e32std.h>
#include <ecom/implementationproxy.h>
#include <w32std.h>
#include <apgtask.h>
#include <apgcli.h>
#include <apgwgnam.h>
#include <apacmdln.h>
#include <centralrepository.h>
#include "FileManagerDebug.h"
#include "FileManagerPrivateCRKeys.h"
#include "filemanageraiwprovider.h"
#include "FileManagerUID.h"

const TImplementationProxy ImplementationTable[] =
    {
    IMPLEMENTATION_PROXY_ENTRY( 0x200110F9, CFileManagerAiwProvider::NewL )
    };
const TUid KUidDefaultFileManager = { KFileManagerUID3 };
const TInt KMaxSortMethodStr = 20;
_LIT( KRootMatch, "?:\\" );


// ======== LOCAL FUNCTIONS ========

// ---------------------------------------------------------------------------
// FindStandaloneAppL
// ---------------------------------------------------------------------------
//
static TBool FindStandaloneAppL(
        RWsSession& aWs, const TUid& aUid, TInt& aWgId )
    {
    FUNC_LOG;

    aWgId = 0; // Used window group id is always greater than zero
    RArray< RWsSession::TWindowGroupChainInfo > windowChain;
    User::LeaveIfError( aWs.WindowGroupList( &windowChain ) );
    CleanupClosePushL( windowChain );
    TInt count( windowChain.Count() );
    for( TInt i( 0 ); i < count; ++i )
        {
        const RWsSession::TWindowGroupChainInfo& entry( windowChain[ i ] );
        CApaWindowGroupName* app = CApaWindowGroupName::NewLC(
            aWs, entry.iId );
        TUid appUid( app->AppUid() );
        CleanupStack::PopAndDestroy( app );
        // Match the app's UID and the embedded status.
        // The app is standalone when there is no parent window group.
        if ( appUid == aUid && entry.iParentId <= 0 )
            {
            // Standalone application found
            aWgId = entry.iId;
            break;
            }
        }
    CleanupStack::PopAndDestroy( &windowChain );
    return aWgId > 0;
    }

// ---------------------------------------------------------------------------
// IsValidFolderToOpenPath
// ---------------------------------------------------------------------------
//
static TBool IsValidFolderToOpenPath( const TDesC& aFullPath )
    {
    FUNC_LOG;

    TInt len( aFullPath.Length() );
    if ( !len )
        {
        return ETrue; // Allow empty to open main view
        }
    // Check that at least root folder exists
    if ( aFullPath.Left( KRootMatch().Length() ).MatchF(
            KRootMatch ) == KErrNotFound )
        {
        return EFalse;
        }
    return ETrue;
    }

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

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::CFileManagerAiwProvider
// ---------------------------------------------------------------------------
//
CFileManagerAiwProvider::CFileManagerAiwProvider()
    {
    FUNC_LOG;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::NewL
// ---------------------------------------------------------------------------
//
CFileManagerAiwProvider* CFileManagerAiwProvider::NewL()
    {
    FUNC_LOG;

    return new ( ELeave ) CFileManagerAiwProvider();
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::~CFileManagerAiwProvider
// ---------------------------------------------------------------------------
//
CFileManagerAiwProvider::~CFileManagerAiwProvider()
    {
    FUNC_LOG;

    delete iService;
    delete iInParamList;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::InitialiseL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::InitialiseL(
        MAiwNotifyCallback& /*aFrameworkCallback*/,
        const RCriteriaArray& /*aInterest*/ )
    {
    FUNC_LOG;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::HandleServiceCmdL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::HandleServiceCmdL(
        const TInt& aCmdId,
        const CAiwGenericParamList& aInParamList,
        CAiwGenericParamList& /*aOutParamList*/,
        TUint /*aCmdOptions*/,
        const MAiwNotifyCallback* aCallback )
    {
    FUNC_LOG;

    INFO_LOG2(
        "CFileManagerAiwProvider::HandleServiceCmdL-aCmdId=%d,aCallback=0x%x",
        aCmdId, aCallback );

    TInt err( KErrNone );
    switch ( aCmdId )
        {
        case KAiwCmdEdit:
            {
            TRAP( err, CmdEditL( aInParamList, aCallback ) );
            break;
            }
        default:
            {
            ERROR_LOG1(
                "CFileManagerAiwProvider::HandleServiceCmdL-InvalidCmd=%d",
                aCmdId );
            break;
            }
        }
    LOG_IF_ERROR2(
        err,
        "CFileManagerAiwProvider::HandleServiceCmdL-aCmdId=%d-err=%d",
        aCmdId, err );
    User::LeaveIfError( err );
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::HandleServerAppExit
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::HandleServerAppExit( TInt /*aReason*/ )
    {
    FUNC_LOG;

    TRAP_IGNORE( NotifyL( KAiwEventCompleted ) );
    iCallback = NULL; // No notifications are needed after app exit
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::CmdEditL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::CmdEditL(
        const CAiwGenericParamList& aInParamList,
        const MAiwNotifyCallback* aCallback )
    {
    FUNC_LOG;

    iCmd = KAiwCmdEdit;
    if ( IsFolderToOpenPathGiven( aInParamList ) )
        {
        if ( IsStandaloneLaunch( aInParamList ) )
            {
            LaunchStandaloneL( aInParamList );
            }
        else
            {
            LaunchEmbeddedL( aInParamList, aCallback );
            }
        }
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::NotifyL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::NotifyL( TInt aEvent )
    {
    FUNC_LOG;

    if ( iCallback && iInParamList )
        {
        CAiwGenericParamList* eventParamList = CAiwGenericParamList::NewL();
        CleanupStack::PushL( eventParamList );
        // Must cast this because of AIW design error
        const_cast< MAiwNotifyCallback* >( iCallback )->HandleNotifyL(
    	    iCmd, aEvent, *eventParamList, *iInParamList );
        CleanupStack::PopAndDestroy( eventParamList );
        }
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::GetAppUidL
// ---------------------------------------------------------------------------
//
TUid CFileManagerAiwProvider::GetAppUidL()
    {
    FUNC_LOG;

    CRepository* cenRep = CRepository::NewLC( KCRUidFileManagerSettings );
    TInt uid( 0 );
    User::LeaveIfError( cenRep->Get( KFileManagerAppUidForAiwService, uid ) );
    CleanupStack::PopAndDestroy( cenRep );
    return TUid::Uid( uid );
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::GetAppUid
// ---------------------------------------------------------------------------
//
TUid CFileManagerAiwProvider::GetAppUid()
    {
    FUNC_LOG;

    if ( !iAppUid.iUid )
        {
        // Read the application to start from CenRep
        TRAPD( err, iAppUid = GetAppUidL() );
        if ( err != KErrNone || !iAppUid.iUid )
            {
            // Use the default application
            iAppUid = KUidDefaultFileManager;
            }
        ERROR_LOG1(
            "CFileManagerAiwProvider::GetAppUid-Uid=0x%x", iAppUid.iUid );
        }
    return iAppUid;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::LaunchEmbeddedL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::LaunchEmbeddedL(
        const CAiwGenericParamList& aInParamList,
        const MAiwNotifyCallback* aCallback )
    {
    FUNC_LOG;

    delete iService;
    iService = NULL;
    delete iInParamList;
    iInParamList = NULL;
    iCallback = NULL;

    // Copy the input params for the launcher and then do the launch
    iInParamList = CAiwGenericParamList::NewL();
    TInt count( aInParamList.Count() );
    for( TInt i( 0 ); i < count; ++i )
        {
        iInParamList->AppendL( aInParamList[ i ] );
        }
    iService = CAknLaunchAppService::NewL( GetAppUid(), this, iInParamList );
    iCallback = aCallback;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::IsStandaloneLaunch
// ---------------------------------------------------------------------------
//
TBool CFileManagerAiwProvider::IsStandaloneLaunch(
        const CAiwGenericParamList& aInParamList )
    {
    FUNC_LOG;

    TBool ret( EFalse );
    TInt i( 0 );
    // Get sort method first
    const TAiwGenericParam* param = aInParamList.FindFirst(
        i, EGenericParamDir, EVariantTypeTInt32 );
    if ( i != KErrNotFound && param )
        {
        // Then, check if standalone is requested
        param = aInParamList.FindNext( i, EGenericParamDir, EVariantTypeTInt32 );
        if ( i != KErrNotFound && param )
            {
            ret = param->Value().AsTInt32();
            }
        }
    return ret;
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::LaunchStandaloneL
// ---------------------------------------------------------------------------
//
void CFileManagerAiwProvider::LaunchStandaloneL(
        const CAiwGenericParamList& aInParamList )
    {
    FUNC_LOG;

    TPtrC folderToOpen( KNullDesC );
    TInt sortMethod( KErrNotFound );
    TInt i( 0 );
    // Get folder path
    const TAiwGenericParam* param = aInParamList.FindFirst(
        i, EGenericParamDir, EVariantTypeDesC );
    if ( i != KErrNotFound && param )
        {
        folderToOpen.Set( param->Value().AsDes() );
        }
    // Get sort method
    param = aInParamList.FindFirst( i, EGenericParamDir, EVariantTypeTInt32 );
    if ( i != KErrNotFound && param )
        {
        sortMethod = param->Value().AsTInt32();
        }

    RWsSession wsSession;
    User::LeaveIfError( wsSession.Connect() );
    CleanupClosePushL( wsSession );
    TInt wgId( 0 );
    TUid appUid( GetAppUid() );
    if ( FindStandaloneAppL( wsSession, appUid, wgId ) )
        {
        // Bring the existing standalone app to foreground
        TApaTask apaTask( wsSession );
        apaTask.SetWgId( wgId );
        apaTask.BringToForeground();
        }
    else
        {
        // Start new standalone app
        TApaAppInfo appInfo;
        RApaLsSession apaLsSession;
        User::LeaveIfError( apaLsSession.Connect() );
        CleanupClosePushL( apaLsSession );
        User::LeaveIfError( apaLsSession.GetAppInfo( appInfo, appUid ) );
        CApaCommandLine* apaCmdLine = CApaCommandLine::NewLC();
        apaCmdLine->SetExecutableNameL( appInfo.iFullName );
        apaCmdLine->SetCommandL( EApaCommandOpen );
        apaCmdLine->SetDocumentNameL( folderToOpen );
        if ( sortMethod != KErrNotFound )
            {
            TBuf8< KMaxSortMethodStr > sortMethodStr;
            sortMethodStr.AppendNum( sortMethod );
            apaCmdLine->SetTailEndL( sortMethodStr );
            }
        TThreadId dummy;
        User::LeaveIfError( apaLsSession.StartApp( *apaCmdLine, dummy ) );
        CleanupStack::PopAndDestroy( apaCmdLine );
        CleanupStack::PopAndDestroy( &apaLsSession );
        }
    CleanupStack::PopAndDestroy( &wsSession );
    }

// ---------------------------------------------------------------------------
// CFileManagerAiwProvider::IsFolderToOpenPathGiven
// ---------------------------------------------------------------------------
//
TBool CFileManagerAiwProvider::IsFolderToOpenPathGiven(
        const CAiwGenericParamList& aInParamList )
    {
    FUNC_LOG;

    TBool ret( EFalse );
    TPtrC folderToOpen( KNullDesC );
    TInt i( 0 );
    // Ensure first that no files are defined, because only folder service
    // is offered by this provider
    const TAiwGenericParam* param = aInParamList.FindFirst(
        i, EGenericParamFile, EVariantTypeAny );
    if ( i == KErrNotFound )
        {
        // Get folder path and check it
        i = 0;
        param = aInParamList.FindFirst(
            i, EGenericParamDir, EVariantTypeDesC );
        if ( i != KErrNotFound && param )
            {
            folderToOpen.Set( param->Value().AsDes() );
            ret = IsValidFolderToOpenPath( folderToOpen );
            }
        }
    if ( !ret )
        {
        ERROR_LOG2(
            "CFileManagerAiwProvider::IsFolderToOpenPathGiven-ret=%d,given=%S",
            ret, &folderToOpen );
        }
    return ret;
    }

// ======== GLOBAL FUNCTIONS ========

// ---------------------------------------------------------------------------
// ImplementationGroupProxy.
// ---------------------------------------------------------------------------
//
EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
    {
    FUNC_LOG;

    aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
    return ImplementationTable;
    }