menucontentsrv/srvsrc/menusrveng.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 21:55:16 +0300
branchRCL_3
changeset 118 8baec10861af
parent 114 a5a39a295112
child 130 67f2ed48ad91
permissions -rw-r--r--
Revision: 201033 Kit: 201035

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

// INCLUDE FILES
#include "menusrveng.h"
#include "menusrv.h"
#include "menusrvsession.h"
#include "menusrvdef.h"
#include "menueng.h"
#include "timeout.h"
#include "menusrvappscanner.h"
#include "mcssatmonitor.h"
#include "menusrvfoldercrnotifier.h"
#include "mcsmenuiconutility.h"
#include "mcsmenuutils.h"
#include "menusrvengutils.h"
#include "mcsdrmhandler.h"
#include "mcscachehandler.h"
#include "mcschildrenhandler.h"
#include "mcsrunningappshandler.h"
#include "mcsgetlisthandler.h"
#include "menusrvobjectfilter.h"
#include <mcsdef.h>
#include <mcsmenufilter.h>


_LIT( KRunning16, "running" );


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

/**
* Close Engine callback function.
* @param aSrvEng CMenuSrvEng as TAny*.
* @return KErrNone.
*/
LOCAL_C TInt CloseSrvEng( TAny* aSrvEng )
    {
    CMenuSrvEng* srvEng = (CMenuSrvEng*)aSrvEng;
    // The timed close should be the last one closing it!
    __ASSERT_DEBUG( 1 == srvEng->AccessCount(), User::Invariant() );
    srvEng->Close(); // Delete it.
    return KErrNone;
    }

/**
* Identity function to search in an array of TPtrC containing Attribute names.
* Identity is the name of attribute.
* @param aLeft Search term.
* @param aRight Array item.
* @return ETrue if names match.
*/
LOCAL_C TBool CmpAttrName(
		const TPtrC& aName1,
		const TPtrC& aName2 )
		    {
		    return ( KErrNone == aName1.Compare( aName2 ) );
		    }

// ==================== MEMBER FUNCTIONS ====================
// ---------------------------------------------------------
// CMenuSrvEng::NewL
// ---------------------------------------------------------
//
CMenuSrvEng* CMenuSrvEng::NewL
( CMenuSrv& aMenuSrv, const TDesC& aContentName )
    {
    CMenuSrvEng* srv = new (ELeave) CMenuSrvEng( aMenuSrv );
    CleanupClosePushL( *srv );
    srv->ConstructL( aContentName );
    CleanupStack::Pop( srv );
    return srv;
    }

// ---------------------------------------------------------
// CMenuSrvEng::~CMenuSrvEng
// ---------------------------------------------------------
//
CMenuSrvEng::~CMenuSrvEng()
    {
    __ASSERT_DEBUG( !iSessions.Count(), User::Invariant() );
    //TODO iCMenuSrvEngUtils
    delete iGetlistHandler;
    delete iDrmHander;
    delete iChildrenHandler;
    delete iTimedClose;
    delete iCacheHandler;
    delete iCMenuSrvEngUtils;
    iSessions.Close();
    iContentName.Close();
    delete iAppScanner;
    delete iFolderNotifier;
    delete iMcsSatMonitor;
    delete iRunningAppsHandler;
    delete iEng;
    iMenuSrv.EngineDeleted();
    }

// ---------------------------------------------------------
// CMenuSrvEng::CMenuSrvEng
// ---------------------------------------------------------
//
CMenuSrvEng::CMenuSrvEng( CMenuSrv& aMenuSrv ): iMenuSrv( aMenuSrv )
    {
    }

// ---------------------------------------------------------
// CMenuSrvEng::ConstructL
// ---------------------------------------------------------
//
void CMenuSrvEng::ConstructL( const TDesC& aContentName )
    {
    if ( !aContentName.Length() )
        {
        // A name is required - only dead engines have empty name.
        User::Leave( KErrArgument );
        }

    iContentName.CreateL( aContentName );
    iTimedClose = CTimeout::NewL
        ( CActive::EPriorityStandard, TCallBack( CloseSrvEng, (TAny*)this ) );
    iEng = CMenuEng::NewL( iContentName, *this );
    if ( iContentName.Length() )
        {
        iCMenuSrvEngUtils = CMenuSrvEngUtils::NewL( *iEng );

        iCacheHandler = CMcsCacheHandler::NewL( *iEng, *iCMenuSrvEngUtils );

        iMcsSatMonitor = CMcsSatMonitor::NewL( *iEng );
    #ifndef __TEST_DISABLE_APPSCAN
        // Start automatic update.
        iAppScanner = CMenuSrvAppScanner::NewL( *iEng, *iCMenuSrvEngUtils );
        // Start automatic update.
        iFolderNotifier =  CMenuSrvFolderCrNotifier::NewL( *iEng );
    #endif
        iRunningAppsHandler = CMcsRunningAppsHandler::NewL(
                *iEng, *iCacheHandler );

        iDrmHander = CMcsDrmHandler::NewL(
                *this, *iCMenuSrvEngUtils, *iCacheHandler );

        iChildrenHandler = CMcsChildrenHandler::NewL( *this, *iCacheHandler);

        iTimedClose->Cancel();
        iTimedClose->After( TTimeIntervalMicroSeconds32( KMenuSrvExitDelay ) );
        }
    }

// ---------------------------------------------------------
// CMenuSrvEng::AddSessionL
// ---------------------------------------------------------
//
void CMenuSrvEng::AddSessionL( CMenuSrvSession* aSession )
    {
    // In AddSessionL() / RemoveSession(), the refcount is
    // increased / decreased. This has no other purpose than sanity-checking.
    // Otherwise, the session count controls the lifetime of this object.
    __ASSERT_DEBUG( KErrNotFound == iSessions.Find( aSession ), \
        User::Invariant() );
    iSessions.AppendL( aSession );
    Open(); // Increase refcount.
    iTimedClose->Cancel(); // Stay alive.
    }

// ---------------------------------------------------------
// CMenuSrvEng::RemoveSession
// ---------------------------------------------------------
//
void CMenuSrvEng::RemoveSession( CMenuSrvSession* aSession )
    {
    TInt i = iSessions.Find( aSession );
    if ( KErrNotFound != i )
        {
        iSessions.Remove( i );
        Close(); // Decrease refcount.
        }
    if ( !iSessions.Count() )
        {
    	iTimedClose->Cancel();
        CActiveScheduler* currentScheduler = CActiveScheduler::Current();
        // No more sessions; schedule self-deletion.
        if (currentScheduler)
        	{
            // No more sessions; schedule self-deletion.
        	iTimedClose->After( TTimeIntervalMicroSeconds32( KMenuSrvExitDelay ) );
        	}
        else
        	{
        	// for Backup&Restore ActiveScheduler is closed ealier so we need
        	// to decrease refcount here (not in CloseSrvEng())
        	Close();
        	}
        }
    }

// ---------------------------------------------------------
// CMenuSrvEng::EngineEvents
// ---------------------------------------------------------
//
void CMenuSrvEng::EngineEvents( TInt aFolder, TInt aEvents )
    {
    // Broadcast to all sessions - for loop will do, we do not
    // expect any session to remove itself during this.
    for ( TInt i = 0; i < iSessions.Count(); i++ )
        {
        iSessions[i]->EngineEvents( aFolder, aEvents );
        }
    if (iDrmHander)
        {
        iDrmHander->EngineEvents( aFolder, aEvents );
        }
    if (iChildrenHandler)
    	{
    	iChildrenHandler->EngineEvents( aFolder, aEvents );
    	}
    if (iRunningAppsHandler)
    	{
    	iRunningAppsHandler->EngineEvents( aFolder, aEvents );
    	}
    if( iCacheHandler && iCacheHandler->iAttrCache.Count() > 0 )
        {
        iCacheHandler->EngineEvents( aEvents );
        }
    }

// ---------------------------------------------------------
// CMenuSrvEng::EngineError
// ---------------------------------------------------------
//
void CMenuSrvEng::EngineError( TInt aErr )
    {
    // Unrecoverable engine error.
    // Broadcast to all sessions before killing ourselves.
    while ( iSessions.Count() )
        {
        CMenuSrvSession* session = iSessions[0];
        iSessions.Remove( 0 );
        Close(); // Decrease refcount.
        session->EngineError( aErr );
        }
    // No more sessions; schedule self-deletion.
    // We could close ourselves immediately, but that would cause the server
    // to exit immediately. Therefore, we use the delayed exit, but clear the
    // name so the server cannot find us and reuse.
    delete iDrmHander; iDrmHander = NULL;
    delete iChildrenHandler, iChildrenHandler = NULL;
    delete iMcsSatMonitor; iMcsSatMonitor = NULL;
    delete iRunningAppsHandler; iRunningAppsHandler = NULL;
    delete iAppScanner; iAppScanner = NULL;
    delete iFolderNotifier; iFolderNotifier = NULL;
    delete iEng; iEng = NULL;

    iContentName.Close();
    iTimedClose->Cancel();
    iTimedClose->After( TTimeIntervalMicroSeconds32( KMenuSrvExitDelay ) );
    }

// CMenuSrvEng::TreeReloaded
// ---------------------------------------------------------
//
void CMenuSrvEng::EngineTreeReloaded()
	{
	if (iAppScanner)
		{
		iAppScanner->ScheduleScan();
		}
	}
void CMenuSrvEng::GetAttributeListL(
		  TInt aId,
		  RArray<TPtrC>& aList )
    {

    const CMenuEngObject& obj = iEng->ObjectL(aId);

    TPtrC name, value;
    TBool localized;
    for ( TInt ndx = 0; obj.GetAttribute( ndx, name, value, localized ); ndx++ )
        {
        if( !( name.Compare( KMenuAttrIconFile ) == KErrNone
            || name.Compare( KMenuAttrIconId ) == KErrNone
            || name.Compare( KMenuAttrMaskId ) == KErrNone
            || name.Compare( KMenuAttrIconSkinMajorId ) == KErrNone
            || name.Compare( KMenuAttrIconSkinMinorId ) == KErrNone ))
            {
            aList.AppendL(name);
            }
        }

    AppendExtendedAttrributesL( obj.Type() , aList );
    }

// ---------------------------------------------------------
// CExtendedMenuItem::GetAttributeL
// ---------------------------------------------------------
//

void CMenuSrvEng::GetAttributeL(
		 TInt aId,
		 const TDesC& aAttrName,
		 TBool& aAttrExists,
		 TDes& aAttrVal )
    {
    TBool dummy;
    TPtrC val(KNullDesC);

    aAttrExists = iEng->ObjectL(aId).FindAttribute( aAttrName, val, dummy);

    if( !aAttrExists )
        {
        aAttrExists = iCacheHandler->iAttrCache.Find( aId, aAttrName, aAttrVal );
        }

    if ( aAttrExists && val!=KNullDesC() )
        {
        aAttrVal = val;
        }
    else if( !aAttrExists )
    	{
    	GetExtendedAttributesL( aId, aAttrName, aAttrExists, aAttrVal );
    	}
    }

// ---------------------------------------------------------
// CMenuSrvEng::GetRunningAppsL()
// ---------------------------------------------------------
//
void CMenuSrvEng::GetRunningAppsL( RArray<TUid>& aArray )
    {
	iRunningAppsHandler->GetRunningAppsL( aArray );
	}

// ---------------------------------------------------------
// CMenuSrvEng::GetRunningAppsL()
// ---------------------------------------------------------
//
void CMenuSrvEng::GetExtendedAttributesL(TInt aId, const TDesC& aAttrName,
        TBool& aAttrExists, TDes& aAttrVal )
    {
    TBool captionInfo(aAttrName.Compare( KMenuAttrShortName ) == KErrNone ||
    aAttrName.Compare( KMenuAttrLongName ) == KErrNone ||
    aAttrName.Compare( KMenuAttrTitleName ) == KErrNone );

    TBool addToCache( ETrue );
    if ( captionInfo )
        {
        CaptionInfoL( aId, aAttrName, aAttrExists, aAttrVal );
        addToCache = EFalse;
        }
    else if ( KErrNone == aAttrName.Compare( KMenuAttrDrmProtection ) )
        {
        AppDrmProtectionL( aId, aAttrExists, aAttrVal );
        }
    else if ( KErrNone == aAttrName.Compare( KRunningStatus ) )
        {
        GetAppRunningL( aId, aAttrExists, aAttrVal );
        }
    else if ( KErrNone == aAttrName.Compare( KChildrenCount ) )
        {
        FolderChildrenCountL( aId, aAttrExists, aAttrVal );
        }
    else if( KErrNone == aAttrName.Compare( KMenuAttrNative ) )
        {
        ApplicationNativeAttributeL( aId, aAttrExists, aAttrVal );
        addToCache = EFalse;
        }
    else // The attribute doesn't present for the item
        {
        aAttrExists = EFalse;
        aAttrVal = KNullDesC();
        }
    if( aAttrExists && addToCache )
        {
        AddToCacheL( aId, aAttrName, aAttrVal );
        }
    }

// ---------------------------------------------------------
// CMenuSrvEng::ApplicationNativeAttributeL
// ---------------------------------------------------------
//
void CMenuSrvEng::ApplicationNativeAttributeL( TInt aId,
        TBool & aAttrExists, TDes & aAttrVal )
	{
	const CMenuEngObject & aEngObj = iEng->ObjectL(aId);

    aAttrExists = EFalse;
    if( aEngObj.Type().CompareF( KMenuTypeApp ) == KErrNone )
        {
        TInt err;
        TUid uid;
        err = iCMenuSrvEngUtils->GetAppUid( aEngObj, uid );
        if( err == KErrNone )
            {
            TBool native(EFalse);
            err = iCMenuSrvEngUtils->IsNativeL( uid, native );
            if( !err )
                {
                aAttrExists = ETrue;
                if( native )
                    {
                    aAttrVal = KMenuTrue();
                    }
                else
                    {
                    aAttrVal = KMenuFalse();
                    }
                }
            }
        }
    if( !aAttrExists )
        {
        aAttrVal = KNullDesC();
        }
	}

// ---------------------------------------------------------
// CMenuSrvEng::AddToCacheL
// ---------------------------------------------------------
//
void CMenuSrvEng::AddToCacheL( TInt aId, const TDesC& aAttrName,
    TDes& aAttrVal )
    {
    CMenuSrvAttr* attr = CMenuSrvAttr::NewLC( aAttrName );
    attr->SetValueL( aAttrVal ); // Takes ownership.
    attr->SetId( aId ); // New in cache -> not changed.
    iCacheHandler->iAttrCache.AppendL( attr );
    CleanupStack::Pop( attr );
    }

// ---------------------------------------------------------
// CMenuSrvEng::CaptionInfoL
// Functions only for KMenuTypeApp type.
// ---------------------------------------------------------
//
void CMenuSrvEng::CaptionInfoL( TInt aId, const TDesC& aAttrName,
    TBool& aExists, TDes& aAttrVal )
    {
    const CMenuEngObject& obj = iEng->ObjectL( aId );
    if ( obj.Type().Compare( KMenuTypeFolder ) == KErrNone )
        {
        TBool localized;
        TPtrC attrvalue;
        TBool attrExists = obj.FindAttribute( KMenuAttrAppGroupName, attrvalue, localized );
        if ( attrExists )
            {
            aExists = ETrue;
            aAttrVal = attrvalue;
            AddToCacheL( aId, KMenuAttrLongName, aAttrVal );
            AddToCacheL( aId, KMenuAttrShortName, aAttrVal );
            AddToCacheL( aId, KMenuAttrTitleName, aAttrVal );
            }
        }
    else if ( obj.Type().Compare( KMenuTypeApp ) == KErrNone )
        {
        aAttrVal = AppCaptionInfoL( obj, aAttrName, aExists );
        }
    else
        {
        aExists = EFalse;
        aAttrVal = KNullDesC();
        }
    }

 // ---------------------------------------------------------
 // CMenuSrvEngUtils::AppDrmProtection
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::AppDrmProtectionL( TInt aId, TBool& aExists, TDes& aAttrVal )
     {
     CMenuSrvEngUtils::TDRMProtectionInfo drmProt;

     if ( KErrNone != iCMenuSrvEngUtils->GetDrmProtectionL(
                                         aId,
                                         drmProt ) )
         {
         aExists = EFalse;
         aAttrVal = KNullDesC();
         }
     else
    	 {
		 aExists = ETrue;
		 switch ( drmProt )
		    {
		    case CMenuSrvEngUtils::EDRMUnknownProtection:
		        {
		        aAttrVal = KMenuDrmUnknown();
		        break;
		        }
		    case CMenuSrvEngUtils::EDRMNotProtected:
		        {
		        aAttrVal = KMenuDrmNotProtected();
		        break;
		        }
		    case CMenuSrvEngUtils::EDRMProtected:
		        {
		        aAttrVal = KMenuDrmProtected();
		        break;
		        }
		    case CMenuSrvEngUtils::EDRMRightsExpired:
		        {
		        aAttrVal = KMenuDrmRightsExpired();
		        break;
		        }
		    default:
		        {
		        User::Invariant();
		        aAttrVal = KNullDesC();
		        }
		    }
    	 }
     }

 // ---------------------------------------------------------
 // CMenuSrvEngUtils::AppCaptionInfoL
 // ---------------------------------------------------------
 //
 TPtrC CMenuSrvEng::AppCaptionInfoL( const CMenuEngObject& aEngObj,
     const TDesC& aAttrName, TBool& aExists )
     {
     TApaAppInfo info;
     TPtrC val( KNullDesC );
     if( KErrNone == iCMenuSrvEngUtils->GetAppInfoL( aEngObj, info ) )
         {
         aExists = ETrue;
         if( aAttrName.Compare( KMenuAttrTitleName ) == KErrNone ||
             aAttrName.Compare( KMenuAttrShortName ) == KErrNone )
             {
             val.Set( info.iShortCaption );
             }
         else if( aAttrName.Compare( KMenuAttrLongName ) == KErrNone )
             {
             val.Set( info.iCaption );
             }
         else
             {
             User::Invariant();
             }
         }
     else
         {
         aExists = EFalse;
         }
     return val;
     }

 // ---------------------------------------------------------
 // CMenuSrvEng::FolderChildrenCountL
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::FolderChildrenCountL(
         TInt aId, TBool& aExists, TDes& aAttrVal )
	 {
	 const CMenuEngObject& obj = iEng->ObjectL(aId);

	 if( obj.Type().CompareF( KMenuTypeFolder ) == KErrNone )
	     {
	     TUint32 childrenCount (0);
		 RArray<TMenuItem> childrenArray;
		 CleanupClosePushL( childrenArray );

		 CMenuFilter* appFilter = CMenuFilter::NewLC();
		 appFilter->SetFlags(0, TMenuItem::EMissing | TMenuItem::EHidden);
		 TMenuSrvObjectFilter engFilter( *appFilter );
		 iEng->GetItemsL(childrenArray, aId, &engFilter, EFalse);
		 childrenCount = childrenArray.Count();

		 CleanupStack::PopAndDestroy( appFilter );
		 CleanupStack::PopAndDestroy( &childrenArray );

         aAttrVal.Num(childrenCount, EDecimal);
         aExists = ETrue;
	     }
	 else
	     {
	     aAttrVal.Append(KNullDesC());
	     aExists = EFalse;
	     }
	 }

 // ---------------------------------------------------------
 // CMenuSrvEngUtils::GetAppRunningL
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::GetAppRunningL( TInt aId, TBool& aExists, TDes& aAttrVal )
	 {
	 aExists = iRunningAppsHandler->GetRunningStatusL(aId);
	 if(aExists)
		 {
		 aAttrVal.Append(KRunning16());
		 }
	 else
		 {
		 aAttrVal.Append(KNullDesC());
		 }
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::GetChildrenCount
 // ---------------------------------------------------------
 //
 TUint CMenuSrvEng::GetChildrenCountL( TInt aId )
	 {
	 TBool attrExists (EFalse);
	 TUint count (0);
	 RBuf attrVal;
	 attrVal.CleanupClosePushL();
	 attrVal.CreateL(KMenuMaxAttrValueLen);

	 // Get folder children count
	 FolderChildrenCountL(aId, attrExists, attrVal);

	 if (attrExists)
		 {
		 TLex lex(attrVal);
		 User::LeaveIfError( lex.Val(count) );
		 }
	 CleanupStack::PopAndDestroy( &attrVal );

	 return count;
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::GetlistSizeL
 // ---------------------------------------------------------
 //
 TInt CMenuSrvEng::GetListSizeL( const TDesC8& aSerializedInput )
	 {
	 delete iGetlistHandler;
	 iGetlistHandler = NULL;

	 iGetlistHandler = CMcsGetlistHandler::NewL( *this );
	 return iGetlistHandler->GetListSizeL( aSerializedInput );
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::CloseOutputBuffer
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::CloseOutputBuffer()
	 {
	 iGetlistHandler->CloseOutputBuffer();
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::CleanAttributeCache
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::CleanAttributeCache()
	 {
	 iCacheHandler->iAttrCache.ResetAndDestroy();
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::GetlistSizeL
 // ---------------------------------------------------------
 //
 TPtrC8 CMenuSrvEng::GetListDataL( )
	 {
	 return iGetlistHandler->GetListDataL( );
	 }

 // ---------------------------------------------------------
 // CMenuSrvEng::AppendExtendedAttrributesL
 // ---------------------------------------------------------
 //
 void CMenuSrvEng::AppendExtendedAttrributesL(
 		const TDesC& aType,
 		RArray<TPtrC>& aList )
{
    if ( KErrNone == aType.Compare( KMenuTypeApp ) )
        {
        if( KErrNotFound == aList.Find( KMenuAttrTitleName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrTitleName ) );
            }
        if( KErrNotFound == aList.Find( KMenuAttrShortName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrShortName ) );
            }
        if( KErrNotFound == aList.Find( KMenuAttrLongName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrLongName ) );
            }
        if( KErrNotFound == aList.Find( KMenuAttrDrmProtection(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrDrmProtection ) );
            }
        }
    else if ( KErrNone == aType.Compare( KMenuTypeFolder ) )
        {
        if( KErrNotFound == aList.Find( KMenuAttrTitleName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrTitleName ) );
            }
        if( KErrNotFound == aList.Find( KMenuAttrShortName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrShortName ) );
            }
        if( KErrNotFound == aList.Find( KMenuAttrLongName(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KMenuAttrLongName ) );
            }
        if( KErrNotFound == aList.Find( KChildrenCount(),
                TIdentityRelation<TPtrC>( CmpAttrName )) )
            {
            aList.AppendL( TPtrC( KChildrenCount ) );
            }
        }
    }


//  End of File