javamanager/javacaptain/src/amc.h
author Shabe Razvi <shaber@symbian.org>
Thu, 02 Sep 2010 15:46:18 +0100
branchRCL_3
changeset 68 67b21c8abcea
parent 19 04becd199f91
permissions -rw-r--r--
Merge RCL_3 fixes with reverted delivery

/*
* 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:  Amc
*
*/

#ifndef AMC_H
#define AMC_H

#include <list>
#include <map>

#include "logger.h"
#include "scopedlocks.h"
#include "javauid.h"

#include "commslistener.h"
#include "commsmessage.h"


#include "applicationruntimeeventsinterface.h"
#include "coreinterface.h"
#include "rtcinterface.h"
#include "amcinterface.h"
#include "amcmessages.h"

using namespace java::comms;
using java::util::Uid;

namespace java
{

namespace captain
{

class ApplicationManagementEventsInterface;

using java::util::ScopedLock;

class Amc : public AmcInterface,
        public ApplicationRuntimeEventsInterface,
        public CommsListener
{
public:
    Amc();
    virtual ~Amc();

    bool start(CoreInterface* aCore,
               ApplicationManagementEventsInterface* aAmEventsDispatcher);
    bool stop();

    // ApplicationRuntimeEventsInterface
    virtual void arLaunched(const Uid& aUID, const int& aRuntimeCommsAddress);
    virtual void arTerminated(const Uid& aUID, const int& aExitCode);

    // CommsListener methods
    virtual void processMessage(CommsMessage& aMessage);

private:

    // Helper functions for request handling
    void handleStart(CommsMessage&);
    void handleStop(CommsMessage&);
    void handleUpdate(CommsMessage&);

    class StopRequest
    {
    public:
        StopRequest(CoreInterface* aCore, const int& aAddress, const int& aModuleId, const int& aMsgRef,
                    const int& aNumOfUIDS, Uid* aUIDS)
                :mCore(aCore), mAddress(aAddress), mModuleId(aModuleId), mMsgRef(aMsgRef)
        {
            JELOG2(EJavaCaptain);
            java::util::ScopedLock lock(mUidsCollectionsMutex);
            for (int i = 0 ; i<aNumOfUIDS ; i++)
            {
                mUidsToBeStopped.push_back(aUIDS[i]);
            }
        }

        bool stopUids()
        {
            JELOG2(EJavaCaptain);
            ScopedLock lock(mUidsCollectionsMutex);

            uids_t::iterator iter = mUidsToBeStopped.begin();
            while (iter != mUidsToBeStopped.end())
            {
                mCore->getRtc()->disable(*iter);
                if (mCore->getRtc()->terminate(*iter))
                {
                    // Was not running in the first place can be directly put to stopped list
                    mUidStatuses.insert(std::make_pair(*iter, 0));
                    iter = mUidsToBeStopped.erase(iter);
                }
                else
                {
                    ++iter;
                }
            }

            // Was the request fulfilled.
            if (!mUidsToBeStopped.size())
            {
                notifyRequester();
                return true;
            }

            return false; // Nope some requests are still pending.
        }

        bool updateStatus(const Uid& aUID, const int& status)
        {
            JELOG2(EJavaCaptain);
            ScopedLock lock(mUidsCollectionsMutex);

            for (uids_t::iterator iter = mUidsToBeStopped.begin() ;
                    iter != mUidsToBeStopped.end() ; ++iter)
            {
                if (*iter == aUID)
                {
                    mUidStatuses.insert(std::make_pair(aUID, status));
                    mUidsToBeStopped.erase(iter);
                    break;
                }
            }

            // Was this the last one ie. the request has been fulfilled.
            if (!mUidsToBeStopped.size())
            {
                notifyRequester();
                return true;
            }

            return false; // Nope some requests are still pending.
        }

        void notifyRequester()
        {
            JELOG2(EJavaCaptain);
            CommsMessage message;
            message.setReceiver(mAddress);
            message.setModuleId(mModuleId);
            message.setMessageRef(mMsgRef);
            setAmcResponseParamaters(message, mUidStatuses.size());

            for (uidStatuses_t::iterator iter = mUidStatuses.begin() ;
                    iter != mUidStatuses.end() ; ++iter)
            {
                message << iter->first << iter->second;
            }

            mCore->getComms()->send(message);
        }

        void sendStopNotAllowed(const int& aNumOfUIDS, Uid* aUIDS)
        {
            JELOG2(EJavaCaptain);
            for (int i = 0 ; i<aNumOfUIDS ; i++)
            {
                updateStatus(aUIDS[i], -1);
            }
        }


    private:
        typedef std::list<Uid>  uids_t;
        uids_t                  mUidsToBeStopped;

        typedef std::map<Uid, int> uidStatuses_t;
        uidStatuses_t           mUidStatuses;
        java::util::ScopedMutex mUidsCollectionsMutex;

        CoreInterface*          mCore;

        const int               mAddress;
        const int               mModuleId;
        const int               mMsgRef;
    };

    CoreInterface*                          mCore;
    ApplicationManagementEventsInterface*   mAmEventsDispatcher;
    StopRequest*                            mStopRequest; // only one at a time
};

} // namespace captain
} // namespace java

#endif // AMC_H