qthighway/xqserviceutil/src/processinfo.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 01:32:41 +0300
changeset 27 6bfad47013df
permissions -rw-r--r--
Revision: 201037 Kit: 201039

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1 of the License.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, 
* see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
*
* Description:                                                         
*
*/

#include "processinfo.h"

#include "xqservicelog.h"

#include <QCoreApplication>

#define TIMER_DELAY 3000000 // 3000000 microseconds == 3s

// static data initialization

ProcessInfoDestroyer *ProcessInfoDestroyer::instance = 0;
CProcessInfo::ProcessInfoMap CProcessInfo::iProcessInfoMap;

// ProcessInfoMap implementation

CProcessInfo::ProcessInfoMap::~ProcessInfoMap()
{
    CProcessInfo::Destroy();
    ProcessInfoDestroyer::disable();
}

// CProcessInfo implementation

CProcessInfo::CProcessInfo(const TUid& appUid):
        CActive(CActive::EPriorityStandard), 
        iAppUid(appUid)
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::CProcessInfo");
    
    CActiveScheduler::Add(this);
}

CProcessInfo::~CProcessInfo()
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::~CProcessInfo");
    
    // Cancel asynch request, normally it should be done in DoCancel() 
    // but we dont wont to cancel request when we cancel active object
    User::CancelMiscNotifier(iStatus);
    
    Cancel();
}

void CProcessInfo::Destroy()
{
    foreach (CProcessInfo* info, iProcessInfoMap.map.values())
        delete info;
    iProcessInfoMap.map.clear();
}

void CProcessInfo::AddProcessL(const TUid& appUid, RProcess& appProcess)
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::AddProcessL");
    
    CProcessInfo* self = new(ELeave) CProcessInfo(appUid);
    CleanupStack::PushL(self);
    self->ConstructL(appProcess);
    CleanupStack::Pop(self);
}

bool CProcessInfo::EnsureProcessCanStartL(const TUid& appUid)
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::EnsureProcessCanStartL");
  
    bool ret = true;
    
    CProcessInfo* previousProcess = iProcessInfoMap.map[appUid.iUid];
    if (previousProcess) {
        // Timer is for ensure that wait will end. 
        // There is possibility that destroying process notification could be lost.
        RTimer securityTimer;
        securityTimer.CreateLocal();
        CleanupClosePushL(securityTimer);
        
        TRequestStatus timerStatus;
        securityTimer.After(timerStatus, TIMER_DELAY);
        User::WaitForRequest(previousProcess->iStatus, timerStatus);
        
        if (previousProcess->iStatus == KRequestPending)
            ret = false;
        
        CleanupStack::PopAndDestroy();
        delete previousProcess;
        iProcessInfoMap.map.remove(appUid.iUid);
    }
    return ret;
}

void CProcessInfo::RunL()
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::RunL");
    
    iProcessInfoMap.map.remove(iAppUid.iUid);
    delete this;
}

void CProcessInfo::ConstructL(RProcess& appProcess)
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::ConstructL");
    
    SetActive();
    
    EnsureProcessCanStartL(iAppUid);
    iProcessInfoMap.map.insert(iAppUid.iUid, this);
    appProcess.NotifyDestruction(iStatus);
    
    ProcessInfoDestroyer::enable();
}

void CProcessInfo::DoCancel()
{
    XQSERVICE_DEBUG_PRINT("CProcessInfo::DoCancel");
    
    // Cancel asynch request, normally it should be done in DoCancel() 
    // but we dont wont to cancel request when we cancel active object.
    // Cancel asynch request is in ~CProcessInfo().
}

// ProcessInfoDestroyer implementation

void ProcessInfoDestroyer::enable()
{
    if (!instance)
        instance = new ProcessInfoDestroyer;
}

void ProcessInfoDestroyer::disable()
{
    if (instance) {
        delete instance;
        instance = 0;
    }
}

ProcessInfoDestroyer::ProcessInfoDestroyer()
{
    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(destroy()));
}

void ProcessInfoDestroyer::destroy()
{
    CProcessInfo::Destroy();
}