javauis/coreui_akn/src/javauiavkonimpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 11 May 2010 16:07:20 +0300
branchRCL_3
changeset 24 0fd27995241b
parent 19 04becd199f91
permissions -rw-r--r--
Revision: v2.1.24 Kit: 201019

/*
* 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: Core ui implementation for the Avkon based UI framework.
*
*/

#include "logger.h"
#include "coreuiavkonimpl.h"
#include "javauiavkonimpl.h"
#include "startscreencontainer.h"

using namespace java::ui;


JavaUiAvkonAppUi::JavaUiAvkonAppUi()
{
    JELOG2(EJavaUI);
    CoreUiAvkonImpl::getInstanceImpl().setJavaUiAppUi(this);
    TTime time;
    time.UniversalTime();
    mStartupTime = time.Int64();
}

JavaUiAvkonAppUi::~JavaUiAvkonAppUi()
{
    JELOG2(EJavaUI);
    mDestroying = true;
    if (mAppView)
    {
        delete mAppView;
        mAppView = 0;
    }
    removeChild(mLcduiChild);
    removeChild(mEswtChild);
    if (mOrientationTimer)
    {
        if (mOrientationTimer->IsActive())
        {
            mOrientationTimer->Cancel();
        }
        delete mOrientationTimer;
        mOrientationTimer = 0;
    }
}

void JavaUiAvkonAppUi::ConstructL()
{
    JELOG2(EJavaUI);

    CoreUiAvkonImpl& coreUiAvkon = CoreUiAvkonImpl::getInstanceImpl();
    const CoreUiParams& coreUiParams = coreUiAvkon.getCoreUiParams();

    TInt appUiFlags = ENoAppResourceFile |
                      EAknEnableSkin |
                      EAknEnableMSK |
                      EAknTouchCompatible;

#ifdef RD_JAVA_S60_RELEASE_9_2
    appUiFlags |= EAknSingleClickCompatible;
#endif

    switch (coreUiParams.getOrientation())
    {
    case java::ui::PORTRAIT:
        appUiFlags |= EAppOrientationPortrait;
        break;
    case java::ui::LANDSCAPE:
        appUiFlags |= EAppOrientationLandscape;
        break;
    }
    BaseConstructL(appUiFlags);
    mIsForeground = true;

    // Set the priority of the process to background for short time
    // in order to avoid Window server panicing the starting app
    // (e.g. menu) if the MIDlet starts to consume 100% cpu.
    const int timeForBg = 1000;
    setBackgroundProcessPriority(timeForBg);
    if (coreUiAvkon.showStartScreen())
    {
        TRAPD(err, mAppView = CStartScreenContainer::NewL(*this, coreUiParams));
        if (err != KErrNone)
        {
            ELOG1(EJavaUI, "JavaUiAvkonAppUi::ConstructL, "
                  "CStartScreenContainer::NewL failed: %d", err);
            delete mAppView;
            mAppView = 0;
        }
        else
        {
            iEikonEnv->RootWin().EnableScreenChangeEvents();
        }
    }
}



void JavaUiAvkonAppUi::HandleForegroundEventL(TBool foreground)
{
    JELOG2(EJavaUI);
    CAknAppUi::HandleForegroundEventL(foreground);
    if (hasStartScreen())
    {
        ASSERT(mAppView);
        mAppView->HandleForeground(foreground);
    }
    if (mActiveChild)
    {
        mActiveChild->HandleForegroundEventL(foreground);
    }
}

void JavaUiAvkonAppUi::HandleSwitchOnEventL(CCoeControl* destination)
{
    JELOG2(EJavaUI);
    if (mActiveChild)
    {
        mActiveChild->HandleSwitchOnEventL(destination);
    }
}

void JavaUiAvkonAppUi::HandleResourceChangeL(TInt type)
{
    JELOG2(EJavaUI);
    CAknAppUi::HandleResourceChangeL(type);
    if (mActiveChild)
    {
        mActiveChild->HandleResourceChangeL(type);
    }
}

void JavaUiAvkonAppUi::HandleApplicationSpecificEventL(TInt type,const TWsEvent& event)
{
    JELOG2(EJavaUI);
    if (mActiveChild)
    {
        mActiveChild->HandleApplicationSpecificEventL(type, event);
    }
    CAknAppUi::HandleApplicationSpecificEventL(type, event);
}

void JavaUiAvkonAppUi::HandleCommandL(TInt command)
{
    JELOG2(EJavaUI);

    if (hasStartScreen())
    {
        if (command == EEikCmdExit ||
                command == EAknSoftkeyBack ||
                command == EAknSoftkeyExit ||
                command == EAknSoftkeyClose)
        {
            RWindowGroup& group = iCoeEnv->RootWin();
            const int KWgOrdinalBackground = -1;
            group.SetOrdinalPosition(KWgOrdinalBackground);
            CoreUiAvkonImpl::getInstanceImpl().shutDownRequestFromWindowServer();
            mStartupCancelled = true;
        }
    }
    else
    {
        if (mActiveChild)
        {
            mActiveChild->HandleCommandL(command);
        }
    }
}

void JavaUiAvkonAppUi::HandleWsEventL(const TWsEvent& event,
                                      CCoeControl* destination)
{
    JELOG2(EJavaUI);

    if (event.Type() == EEventScreenDeviceChanged)
    {
        LOG(EJavaUI, EInfo, "Got orientation change event");
        // This is for handling the rotation event.
        // We keep the current priority for a short period. If we are in
        // foreground, this gives us all the available CPU to do the
        // orientation change as fast as possible.
        // After the timer elapses, we set the process priority to BG for
        // some period. This is done in order to avoid problems in such
        // MIDlets that consume 100% cpu.

        const int timeForCurrentPriority = 1000;
        setDefaultProcessPriority(timeForCurrentPriority);
    }

    if (event.Type() == EEventFocusLost)
    {
        mIsForeground = false;
        if (hasStartScreen())
        {
            ASSERT(mAppView);
            mAppView->HandleForeground(false);   
        }
    }
    else if (event.Type() == EEventFocusGained)
    {
        mIsForeground = true;
        if (hasStartScreen())
        {
            ASSERT(mAppView);
            mAppView->HandleForeground(true);
        }
    }

    bool eventBlocked = false;
    if (mActiveChild)
    {
        eventBlocked = mActiveChild->HandleWsEventL(event, destination);
    }
    if (!eventBlocked)
    {
        CAknAppUi::HandleWsEventL(event, destination);
    }
}

void JavaUiAvkonAppUi::setLcduiChild(CoreAppUiChild* child, int resourceFileOffset)
{
    JELOG2(EJavaUI);
    if (!mLcduiChild)
    {
        mLcduiChild = child;
        mActiveChild = mLcduiChild;
        mPassiveChild = mEswtChild;
        mLcduiResourceFile = resourceFileOffset;
    }
}

void JavaUiAvkonAppUi::setEswtChild(CoreAppUiChild* child)
{
    JELOG2(EJavaUI);
    if (!mEswtChild)
    {
        mEswtChild = child;
        mActiveChild = mEswtChild;
        mPassiveChild = mLcduiChild;
    }
}

void JavaUiAvkonAppUi::removeChild(CoreAppUiChild* child)
{
    JELOG2(EJavaUI);

    if (child == mLcduiChild)
    {
        delete mLcduiChild;
        CCoeEnv::Static()->DeleteResourceFile(mLcduiResourceFile);
        mLcduiChild = 0;
        mLcduiResourceFile = 0;
        mActiveChild = mEswtChild;
    }
    else if (child == mEswtChild)
    {
        delete mEswtChild;
        mEswtChild = 0;
        mActiveChild = mLcduiChild;
    }
    if (child == mPassiveChild)
    {
        mPassiveChild = 0;
    }
}

CoreAppUiChild* JavaUiAvkonAppUi::getLcduiChild() const
{
    JELOG2(EJavaUI);
    return mLcduiChild;
}

bool JavaUiAvkonAppUi::hasStartScreen() const
{
    return mAppView && !mAppViewExiting;
}

void JavaUiAvkonAppUi::stopStartScreen(bool aFullScreenUi /*=true*/)
{
    JELOG2(EJavaUI);

    if (hasStartScreen())
    {
        if (aFullScreenUi && mIsForeground && IsForeground())
        {
            TRAPD(err, mAppView->AsyncSaveL(TCallBack(JavaUiAvkonAppUi::AsyncSaveComplete, this)));
            if (KErrNone != err)
            {
                ELOG1(EJavaUI, "JavaUiAvkonAppUi::stopStartScreen, "
                      "CStartScreenContainer::AsyncSaveL failed: %d", err);
            }
            else
            {
                mAppViewExiting = ETrue;
            }
        }

        if (!mAppViewExiting)
        {
            delete mAppView;
            mAppView = 0;
        }
    }
}

bool JavaUiAvkonAppUi::isClosingPossible() const
{
    JELOG2(EJavaUI);
    return mActiveChild == 0;
}

TInt64 JavaUiAvkonAppUi::startupTime() const
{
    return mStartupTime;
}

bool JavaUiAvkonAppUi::isForeground() const
{
    JELOG2(EJavaUI);
    return mIsForeground;
}

void JavaUiAvkonAppUi::glueSetKeyBlockMode(TAknKeyBlockMode aMode)
{
    JELOG2(EJavaUI);
    SetKeyBlockMode(aMode);
}

bool JavaUiAvkonAppUi::hidesIndicators() const
{
    return hasStartScreen() && mAppView->HidesIndicators();
}

bool JavaUiAvkonAppUi::isStartupCancelled() const
{
    return mStartupCancelled;
}

TInt JavaUiAvkonAppUi::orientationTimerCallback(TAny* ptr)
{
    JELOG2(EJavaUI);
    JavaUiAvkonAppUi* appUi = reinterpret_cast<JavaUiAvkonAppUi*>(ptr);
    appUi->handleElapsedTimer();
    return 0;
}

void JavaUiAvkonAppUi::handleElapsedTimer()
{
    JELOG2(EJavaUI);
    LOG(EJavaUI, EInfo, "handleElapsedTimer");
    if (mIsDefaultPriorityInUse)
    {
        // We have now been the defined time in default priority. Now
        // it is time to explicitly set to background priority for a while.
        const int timeForBg = 6000;
        int status = setBackgroundProcessPriority(timeForBg);
        if (status != KErrNone)
        {
            ELOG1(EJavaUI, "JavaUiAvkonAppUi::handleElapsedTimer, "
                  "setBackgroundProcessPriority failed: %d", status);
            // Setting timer failed, so lets go immediately back to default priority.
            setDefaultProcessPriority(0);
        }
    }
    else
    {
        setDefaultProcessPriority(0);
        if (mOrientationTimer->IsActive())
        {
            mOrientationTimer->Cancel();
        }
        delete mOrientationTimer;
        mOrientationTimer = 0;
    }
}

int JavaUiAvkonAppUi::setDefaultProcessPriority(TInt time)
{
    JELOG2(EJavaUI);
    LOG1(EJavaUI, EInfo, "Setting default priority: %d", RProcess().Priority());
    // Client process's priority is set to EPriorityForeground when the
    // window group takes focus, and set to EPriorityBackground when it
    // loses focus.
    iCoeEnv->WsSession().ComputeMode(RWsSession::EPriorityControlComputeOff);
    mIsDefaultPriorityInUse = true;
    TRAPD(status, startTimerL(time));
    return status;
}

int JavaUiAvkonAppUi::setBackgroundProcessPriority(TInt time)
{
    JELOG2(EJavaUI);

    // eSWT MIDlets should not be put to background priority after orientation change.
    // Installer drawing is havily affected if the priority of the process is lowered.
    if (mActiveChild == mEswtChild)
        return KErrNone;
    if (mActiveChild == mLcduiChild)
        return KErrNone;

    LOG1(EJavaUI, EInfo, "Setting background priority: %d", RProcess().Priority());
    // Client process's priority is always set to EPriorityBackground.
    iCoeEnv->WsSession().ComputeMode(RWsSession::EPriorityControlComputeOn);
    mIsDefaultPriorityInUse = false;
    TRAPD(status, startTimerL(time));
    return status;
}


void JavaUiAvkonAppUi::startTimerL(TInt time)
{
    JELOG2(EJavaUI);
    if (time > 0)
    {
        LOG1(EJavaUI, EInfo, "startTimer for %d ms.", time);
        if (mOrientationTimer == 0)
        {
            mOrientationTimer = CPeriodic::NewL(CActive::EPriorityStandard);
        }
        else
        {
            if (mOrientationTimer->IsActive())
            {
                mOrientationTimer->Cancel();
            }
        }
        mOrientationTimer->Start(time * 1000, 10 * 1000 * 1000,
                                 TCallBack(orientationTimerCallback, this));
    }
}

TInt JavaUiAvkonAppUi::AsyncSaveComplete(TAny* aObj)
{
    JavaUiAvkonAppUi* appUi = static_cast<JavaUiAvkonAppUi*>(aObj);
    if (appUi)
        appUi->DoAsyncSaveComplete();
    return 0;
}

void JavaUiAvkonAppUi::DoAsyncSaveComplete()
{
    delete mAppView;
    mAppView = 0;
}

TUid JavaUiAvkonApplication::AppDllUid() const
{
    JELOG2(EJavaUI);
    return CoreUiAvkonImpl::getInstanceImpl().getMidletTUid();
}


CApaDocument* JavaUiAvkonApplication::CreateDocumentL()
{
    JELOG2(EJavaUI);
    CApaDocument* document = new(ELeave) JavaUiAvkonDocument(*this);
    return document;
}


TFileName JavaUiAvkonApplication::ResourceFileName() const
{
    JELOG2(EJavaUI);
    return TFileName();
}


JavaUiAvkonDocument::JavaUiAvkonDocument(JavaUiAvkonApplication& application)
        : CAknDocument(application)
{
    JELOG2(EJavaUI);
}


CAknAppUi* JavaUiAvkonDocument::CreateAppUiL()
{
    JELOG2(EJavaUI);
    // No need to push the AppUi onto the cleanup stack as it registers itself
    // with the EikonEnv upon creation.
    JavaUiAvkonAppUi* appUi = new(ELeave) JavaUiAvkonAppUi;
    return appUi;
}

CApaApplication* newJavaApplication()
{
    JELOG2(EJavaUI);
    CApaApplication* app = new JavaUiAvkonApplication();
    return app;
}