javauis/coreui_akn/src/startupscreen/startscreencontainer.cpp
changeset 21 2a9601315dfc
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/coreui_akn/src/startupscreen/startscreencontainer.cpp	Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,549 @@
+/*
+ * 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: The CCoeControl for the start screen.
+ *
+ */
+
+#include <aknlayoutscalable_apps.cdl.h>
+#include <data_caging_path_literals.hrh>
+#include <AknsDrawUtils.h>
+#include <AknUtils.h>
+#ifdef RD_JAVA_UI_ALFDRAWER_ENABLED
+#include <alf/alfdrawer.h>
+#endif // RD_JAVA_UI_ALFDRAWER_ENABLED
+
+#include "startscreencontainer.h"
+#include "startscreen.h"
+#include "logger.h"
+#include "eswt.h"
+
+const int KStartScreenTimeLimit = 10000; // miliseconds
+const int KStartScreenFadeTimeLimit = 3000; // miliseconds
+const int KStartScreenFadeTreshold = 500; // miliseconds
+
+CStartScreenContainer* CStartScreenContainer::NewL(
+    java::ui::JavaUiAvkonAppUi& appUi,
+    const java::ui::CoreUiParams& coreUiParams)
+{
+    JELOG2(EJavaUI);
+    CStartScreenContainer* self = new(ELeave) CStartScreenContainer(appUi,
+            coreUiParams);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+CStartScreenContainer::~CStartScreenContainer()
+{
+    JELOG2(EJavaUI);
+
+    if (HidesIndicators())
+        ShowIndicators(ETrue);
+
+    mFader.FadeBehindPopup(this, this, EFalse);
+    mAppUi.RemoveFromStack(this);
+
+    if (mStartScreenTimer)
+    {
+        mStartScreenTimer->Stop();
+        delete mStartScreenTimer;
+        mStartScreenTimer = 0;
+    }
+    if (mStartScreen)
+    {
+        delete mStartScreen;
+        mStartScreen = 0;
+    }
+    if (mCba)
+    {
+        delete mCba;
+        mCba = 0;
+    }
+    if (mBgContext)
+    {
+        delete mBgContext;
+        mBgContext = 0;
+    }
+}
+
+void CStartScreenContainer::HandleForeground(bool aForeground)
+{
+    JELOG2(EJavaUI);
+
+    if (!aForeground)
+    {
+        if (!mCba)
+        {
+            mStartScreenTimer->Pause();
+        }
+    }
+    else
+    {
+        if (!mCba)
+        {
+            mStartScreenTimer->Start();
+        }
+    }
+}
+
+void CStartScreenContainer::ShowExitScreen()
+{
+    JELOG2(EJavaUI);
+
+    TRect rect;
+    AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, rect);
+
+    // Turn CBA on
+    TRAPD(err, mCba = CEikButtonGroupContainer::NewL(
+                          CEikButtonGroupContainer::ECba,
+                          CEikButtonGroupContainer::EHorizontal,
+                          &mAppUi,
+                          0,
+                          CEikButtonGroupContainer::EAddToStack));
+    if (err != KErrNone)
+    {
+        ELOG1(EJavaUI, "CStartScreenContainer::ShowExitScreen, "
+              "CEikButtonGroupContainer::NewL failed: %d", err);
+        return;
+    }
+    mCba->SetBoundingRect(rect);
+
+    // Show "Exit" RSK on CBA
+    TRAP(err, mCba->SetCommandSetL(R_AVKON_SOFTKEYS_EXIT));
+    if (err != KErrNone)
+    {
+        ELOG1(EJavaUI, "CStartScreenContainer::ShowExitScreen, "
+              "CEikButtonGroupContainer::SetCommandSetL failed: %d", err);
+    }
+
+    // Create background, as we stop being transparent
+    if (!mBgContext)
+    {
+        mBgContext = CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgScreen,
+                     rect, ETrue);
+    }
+
+    // Add to stack if not already added.
+    if (!mStartScreen || mStartScreen->IsEmpty())
+    {
+        SetRect(rect);
+        mAppUi.AddToStackL(this);
+        ActivateL();
+        MakeVisible(ETrue);
+    }
+
+    // Stop fading behind if user defined start screen.
+    if (mStartScreen && mStartScreen->Type() == CStartScreen::EStartScreenUserDefined)
+    {
+        mFader.FadeBehindPopup(this, this, EFalse);
+        DrawDeferred();
+    }
+
+    // Show the status pane (title pane)
+    CEikStatusPane* pane = mAppUi.StatusPane();
+    pane->MakeVisible(ETrue);
+    if (HidesIndicators())
+        ShowIndicators(EFalse);
+
+    // Push behind SP and CBA
+    Window().SetOrdinalPosition(0, -1);
+
+    mExitScreenOn = ETrue;
+}
+
+void CStartScreenContainer::AsyncSaveL(TCallBack aCallBack)
+{
+    if (!mStartScreen || mStartScreen->Type() != CStartScreen::EStartScreenAutomatic)
+    {
+        aCallBack.CallBack();
+        return;
+    }
+
+    // Save the new start time if going over the treshold.
+    TTime time;
+    time.UniversalTime();
+    TInt64 newTime = time.Int64() - mAppUi.startupTime();
+    newTime /= 1000; // from microseconds to miliseconds
+    if (mStartTimeKnown)
+    {
+        if (mFaded)
+        {
+            // The application started in more than 3 seconds.
+            // Override only if lower than 2.5 seconds.
+            if (newTime + KStartScreenFadeTreshold < KStartScreenFadeTimeLimit)
+                mStartScreen->SaveStartupTime(newTime);
+        }
+        else
+        {
+            // The application started in less than 3 seconds.
+            // Override only if higher than 3.5 seconds.
+            if (newTime - KStartScreenFadeTreshold > KStartScreenFadeTimeLimit)
+                mStartScreen->SaveStartupTime(newTime);
+        }
+    }
+    else
+    {
+        mStartScreen->SaveStartupTime(newTime);
+    }
+
+    // Take away the start screen, to uncover the app's UI.
+    HideL();
+
+    // Ensure the app's UI is flushed to the screen and take the screenshot.
+    FlushScreenL();
+    mStartScreen->AsyncSaveScreenL(aCallBack);
+}
+
+void CStartScreenContainer::HideL()
+{
+    mFaded = EFalse;
+
+    // The application is starting to draw so no need for exit screen.
+    if (mStartScreenTimer)
+    {
+        mStartScreenTimer->Stop();
+    }
+
+    // If the exit screen has been shown, hide the CBA
+    if (mCba)
+    {
+        mCba->MakeVisible(EFalse);
+    }
+
+    // Keep the window on the screen but lower the z-order
+    // The following lines of code must stay in this order!
+    FlushScreenL();
+    Window().SetOrdinalPosition(0, ESwtWinPriorityInactiveTopShell);
+    DrawNow();
+}
+
+TBool CStartScreenContainer::HidesIndicators() const
+{
+    return (mStartScreen && mStartScreen->Type() == CStartScreen::EStartScreenAutomatic);
+}
+
+void CStartScreenContainer::Draw(const TRect& aRect) const
+{
+    JELOG2(EJavaUI);
+    CWindowGc& gc = SystemGc();
+    if (mBgContext)
+    {
+        AknsDrawUtils::Background(AknsUtils::SkinInstance(), mBgContext, this, gc, aRect);
+    }
+    if (mStartScreen)
+    {
+        mStartScreen->Draw(gc, Rect());
+    }
+    if (mFaded)
+    {
+        TRgb col(0, 0, 0);
+        col.SetAlpha(125);
+        gc.SetBrushColor(col);
+        gc.SetPenStyle(CGraphicsContext::ENullPen);
+        gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+        gc.DrawRect(Rect());
+    }
+}
+
+void CStartScreenContainer::HandleResourceChange(TInt aType)
+{
+    JELOG2(EJavaUI);
+    CCoeControl::HandleResourceChange(aType);
+
+    if (aType == KEikDynamicLayoutVariantSwitch)
+    {
+        TRect rect;
+        AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, rect);
+        SetRect(rect);
+        if (mBgContext)
+        {
+            mBgContext->SetRect(rect);
+        }
+
+        if (mStartScreen)
+        {
+            mStartScreen->HandleResolutionChange();
+            if (!mExitScreenOn)
+            {
+                MakeVisible(!mStartScreen->IsEmpty());
+            }
+        }
+
+        DrawDeferred();
+    }
+}
+
+TInt CStartScreenContainer::CountFadedComponents()
+{
+    return 1;
+}
+
+CCoeControl* CStartScreenContainer::FadedComponent(TInt /*aIndex*/)
+{
+    return this;
+}
+
+CStartScreenContainer::CStartScreenContainer(java::ui::JavaUiAvkonAppUi& appUi,
+        const java::ui::CoreUiParams& coreUiParams)
+        : CCoeControl()
+        , mAppUi(appUi)
+        , mCoreUiParams(coreUiParams)
+{
+    JELOG2(EJavaUI);
+}
+
+void CStartScreenContainer::ConstructL()
+{
+    JELOG2(EJavaUI);
+
+    mStartScreenTimer = CStartScreenTimer::NewL(*this);
+
+    CreateWindowL();
+    SetMopParent(&mAppUi);
+
+    // The start screen window needs to be on top of the ui,
+    // in order to hide the quirks of ui initialization.
+    Window().SetOrdinalPosition(0, 10);
+
+    TRect rect;
+    AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, rect);
+
+    TBool transparent = EFalse;
+    if (mCoreUiParams.getScreenMode() == java::ui::MIDLET_DEFINED_SCREEN ||
+            mCoreUiParams.getScreenMode() == java::ui::USER_DEFINED_SCREEN)
+    {
+        // User defined start screen.
+        TRAPD(err,
+              mStartScreen = CStartScreen::NewL(CStartScreen::EStartScreenUserDefined,
+                                                mCoreUiParams));
+        if (KErrNone != err)
+        {
+            ELOG1(EJavaUI, "CStartScreenContainer::ConstructL, "
+                  "CStartScreen::NewL failed: %d", err);
+        }
+        else
+        {
+            // There is no point in having empty user defined start screen.
+            if (mStartScreen->IsEmpty())
+            {
+                delete mStartScreen;
+                mStartScreen = 0;
+            }
+        }
+
+        if (mStartScreen)
+        {
+            RWindow& window = Window();
+
+            // Try to enable window transparency
+            if (CAknEnv::Static()->TransparencyEnabled())
+            {
+                window.SetRequiredDisplayMode(EColor16MA);
+                if (window.SetTransparencyAlphaChannel() == KErrNone)
+                {
+                    window.SetBackgroundColor(~0);
+                    transparent = ETrue;
+                }
+            }
+
+            // If the user start image is fullscreen, no need for fading behind
+            TSize imgSize = mStartScreen->Size();
+            if (imgSize.iWidth < rect.Width() || imgSize.iHeight < rect.Height())
+            {
+                mFader.FadeBehindPopup(this, this, ETrue);
+            }
+
+            if (!transparent)
+            {
+                mBgContext = CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgScreen,
+                             rect, ETrue);
+            }
+        }
+    }
+
+    if (!mStartScreen)
+    {
+        // Automatic start screen
+        mStartScreen = CStartScreen::NewL(CStartScreen::EStartScreenAutomatic,
+                                          mCoreUiParams);
+        if (!mStartScreen->IsEmpty())
+        {
+            TInt64 period = mStartScreen->LoadStartupTime();
+            if (period > 0)
+            {
+                mStartTimeKnown = ETrue;
+                if (period > KStartScreenFadeTimeLimit)
+                {
+                    // Possible alternative, but too dark:
+                    // Window().SetFaded(ETrue, RWindowTreeNode::EFadeWindowOnly);
+                    mFaded = ETrue;
+                }
+            }
+        }
+    }
+
+    if (HidesIndicators())
+        ShowIndicators(EFalse);
+
+    if (mStartScreen && !mStartScreen->IsEmpty())
+    {
+        SetRect(rect);
+        mAppUi.AddToStackL(this);
+        ActivateL();
+        MakeVisible(ETrue);
+    }
+    else
+    {
+        MakeVisible(EFalse);
+    }
+}
+
+void CStartScreenContainer::ShowIndicator(CEikStatusPane* aSp, TInt aId, TBool aVisible)
+{
+    TUid uid = TUid::Uid(aId);
+    CEikStatusPaneBase::TPaneCapabilities subPane = aSp->PaneCapabilities(uid);
+    if (subPane.IsPresent() && subPane.IsAppOwned())
+    {
+        CCoeControl* ctrl = NULL;
+        TRAP_IGNORE(ctrl = aSp->ControlL(uid));
+        if (ctrl)
+        {
+            ctrl->MakeVisible(aVisible);
+        }
+    }
+}
+
+void CStartScreenContainer::ShowIndicators(TBool aVisible)
+{
+    CEikStatusPane* sp = mAppUi.StatusPane();
+    if (!sp)
+        return;
+
+    ShowIndicator(sp, EEikStatusPaneUidSignal, aVisible);
+    ShowIndicator(sp, EEikStatusPaneUidBattery, aVisible);
+    ShowIndicator(sp, EEikStatusPaneUidIndic, aVisible);
+    ShowIndicator(sp, EEikStatusPaneUidMessage, aVisible);
+    ShowIndicator(sp, EEikStatusPaneUidClock, aVisible);
+    ShowIndicator(sp, EEikStatusPaneUidDigitalClock, aVisible);
+
+    if (aVisible)
+        sp->DrawNow();
+}
+
+void CStartScreenContainer::FlushScreenL()
+{
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    CAlfDrawer* drawer = CAlfDrawer::NewL();
+    CleanupStack::PushL(drawer);
+    TInt err = drawer->Finish();
+    CleanupStack::PopAndDestroy(drawer);
+
+    if (KErrNone != err)
+    {
+        // Try again
+        ELOG1(EJavaUI, "CStartScreenContainer::FlushScreenL, "
+              "CAlfDrawer::Finish failed: %d", err);
+        iEikonEnv->WsSession().Flush();
+        iEikonEnv->WsSession().Finish();
+    }
+#else
+    iEikonEnv->WsSession().Flush();
+    iEikonEnv->WsSession().Finish();
+#endif // RD_JAVA_S60_RELEASE_9_2
+}
+
+CStartScreenTimer* CStartScreenTimer::NewL(CStartScreenContainer& aSc)
+{
+    JELOG2(EJavaUI);
+
+    CStartScreenTimer* self = new(ELeave) CStartScreenTimer(aSc);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+CStartScreenTimer::~CStartScreenTimer()
+{
+    JELOG2(EJavaUI);
+    Cancel();
+}
+
+void CStartScreenTimer::Start()
+{
+    JELOG2(EJavaUI);
+    // Converting secs to micro secs.
+    mTimerStartTime.HomeTime();
+    if (!IsActive())
+    {
+        TInt timerVal = (TInt)(mTimerValue.Int64());
+        if (timerVal > 0)
+        {
+            After(timerVal);
+        }
+        else
+        {
+            mSc.ShowExitScreen();
+        }
+    }
+}
+
+void CStartScreenTimer::Pause()
+{
+    JELOG2(EJavaUI);
+    if (IsActive())
+    {
+        TTime currentTime;
+        currentTime.HomeTime();
+        TTimeIntervalMicroSeconds delta(currentTime.MicroSecondsFrom(
+                                            mTimerStartTime));
+        mTimerValue = mTimerValue.Int64() - delta.Int64();
+        Stop();
+    }
+}
+
+void CStartScreenTimer::Stop()
+{
+    JELOG2(EJavaUI);
+    if (IsActive())
+        Cancel();
+}
+
+void CStartScreenTimer::RunL()
+{
+    JELOG2(EJavaUI);
+    mSc.ShowExitScreen();
+}
+
+void CStartScreenTimer::DoCancel()
+{
+    CTimer::DoCancel();
+}
+
+CStartScreenTimer::CStartScreenTimer(
+    CStartScreenContainer& aSc) :
+        CTimer(CActive::EPriorityStandard), mSc(aSc), mTimerValue(
+            KStartScreenTimeLimit * 1000)
+
+{
+    JELOG2(EJavaUI);
+    CActiveScheduler::Add(this);
+}
+
+void CStartScreenTimer::ConstructL()
+{
+    JELOG2(EJavaUI);
+    CTimer::ConstructL();
+}