contentstorage/casrv/carunningappmonitor/src/carunningappmonitor.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:16:09 +0300
changeset 61 8e5041d13c84
parent 60 f62f87b200ec
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* 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: cadrmscanner.mmp
*
*/

#include <apgwgnam.h>

#include "carunningappmonitor.h"
#include "cadef.h"
#include "castoragetask.h"
#include "cainnerquery.h"
#include "cainnerentry.h"
#include "caarraycleanup.inl"
#include "castorageproxy.h"

const TInt KRunningAppGranularity(10);
// -----------------------------------------------------------------------------
// ExecuteL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::ExecuteL( MCaRunningTaskHandler& aTaskHandler,
                                     CCaStorageProxy& aStorage )
    {
    CCaRunningAppMonitor* self = 
        new (ELeave)CCaRunningAppMonitor( aTaskHandler, aStorage );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    }

// -----------------------------------------------------------------------------
// ~CCaRunningAppMonitor
// -----------------------------------------------------------------------------
//
CCaRunningAppMonitor::~CCaRunningAppMonitor()
    {
    Cancel();
    iWg.Close();
    iSession.Close();
    iRunningTasks.Close();
    }

// -----------------------------------------------------------------------------
// CCaRunningAppMonitor
// -----------------------------------------------------------------------------
//
CCaRunningAppMonitor::CCaRunningAppMonitor( MCaRunningTaskHandler& aTaskHandler, 
                                            CCaStorageProxy& aStorage )
:
CActive( EPriorityStandard ),
iTaskHandler( aTaskHandler ),
iStorage( aStorage )
    {
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// ConstructL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::ConstructL()
    {
    //Create window server observer
    ConstractObserverL();
    
    //start listen
    Subscribe();
    
    //At plugin start mark all entry as "not running"
    ResetStorageL();
    
    iTaskHandler.RegisterTaskL(this);//this operation has to be as a last one
    }

// -----------------------------------------------------------------------------
// UpdateRunningAppStorageL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::UpdateRunningAppStorageL()
    {
    RArray<RWsSession::TWindowGroupChainInfo> 
        windowGroupIds(KRunningAppGranularity, 
                       _FOFF( RWsSession::TWindowGroupChainInfo, iId ));
    CleanupClosePushL( windowGroupIds );
    User::LeaveIfError( iSession.WindowGroupList( 0, &windowGroupIds ) );
    TInt itemIndex( KErrNotFound );
    
    //Verify what apps has stopped
    THashMapIter<TInt, TUid> iterator( iRunningTasks );
    RWsSession::TWindowGroupChainInfo item = { KErrNotFound, KErrNotFound };
    while( 0 != iterator.NextKey() )
        {
        item.iId = *iterator.CurrentKey();
        itemIndex = windowGroupIds.Find(item);
        if(KErrNotFound == itemIndex)
            {
            //push new task to register application update in storage
            CCaStorageTask::ExecuteL( iTaskHandler,
                                      iStorage,
                                      *iterator.CurrentValue(),
                                      KErrNotFound );
            iterator.RemoveCurrent();
            }
        else
            {
            //application is already registered.
            //remove entry to skip its processing
            windowGroupIds.Remove( itemIndex );
            }
        }
    
    //Verify what apps has started
    const TInt count(windowGroupIds.Count());
    for(TInt iter(0); iter < count; ++iter)
        {
        if( 0 >= windowGroupIds[iter].iParentId )
            {
            //push new task to register application update in storage and
            //register it running task list 
            CApaWindowGroupName* name = 
                CApaWindowGroupName::NewLC( iSession, windowGroupIds[iter].iId);
            if( 0 != name->AppUid().iUid )
                {
                CCaStorageTask::ExecuteL( iTaskHandler,
                                          iStorage,
                                          name->AppUid(),
                                          windowGroupIds[iter].iId );
                iRunningTasks.Insert( windowGroupIds[iter].iId,
                                      name->AppUid() );
                }
            CleanupStack::PopAndDestroy( name );
            }
        }
    CleanupStack::PopAndDestroy( &windowGroupIds );
    }

// -----------------------------------------------------------------------------
// Subscribe
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::Subscribe()
    {
    if( !IsActive() )
        {
        iSession.EventReady( &iStatus );
        SetActive();
        }
    }

// -----------------------------------------------------------------------------
// ConstractObserverL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::ConstractObserverL()
{
    User::LeaveIfError( iSession.Connect() );
    iWg = RWindowGroup( iSession );
    User::LeaveIfError( iWg.Construct( 
                        reinterpret_cast<TUint32>( &iWg ) ) );
    iWg.DisableFocusChangeEvents();
    iWg.DisableModifierChangedEvents();
    iWg.DisableOnEvents();
    iWg.DisableScreenChangeEvents();

    //enable notifications about group lists
    User::LeaveIfError( iWg.EnableGroupListChangeEvents() );
}

// -----------------------------------------------------------------------------
// ResetStorageL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::ResetStorageL()
{
    CCaInnerQuery* allAppQuery = CCaInnerQuery::NewLC();
    allAppQuery->SetFlagsOn( ERunning );
    RPointerArray<CCaInnerEntry> entries;
    CleanupResetAndDestroyPushL( entries );
    iStorage.GetEntriesL( allAppQuery, entries );
    for( TInt i(0); i < entries.Count(); ++i )
        {
        CCaStorageTask::ExecuteL( iTaskHandler,
                                  iStorage,
                                  TUid::Uid(entries[i]->GetUid()),
                                  KErrNotFound );
        }
    CleanupStack::PopAndDestroy(&entries);
    CleanupStack::PopAndDestroy(allAppQuery);
}

// -----------------------------------------------------------------------------
// RunL
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::RunL()
    {
    User::LeaveIfError( iStatus.Int() );
    TWsEvent event;
    iSession.GetEvent( event );
    Subscribe();//new subscribtion has to be called after picking event
    if( EEventWindowGroupListChanged == event.Type() )
        {
        UpdateRunningAppStorageL();
        }
    }

// -----------------------------------------------------------------------------
// RunError
// -----------------------------------------------------------------------------
//
TInt CCaRunningAppMonitor::RunError( TInt /*aError*/ )
    {
    //ignore error
    Subscribe();
    return KErrNone;
    }

// -----------------------------------------------------------------------------
// DoCancel
// -----------------------------------------------------------------------------
//
void CCaRunningAppMonitor::DoCancel()
    {
    if( IsActive() )
        {
        iSession.EventReadyCancel();
        }
    }