idlehomescreen/nativeuicontroller/src/appui.cpp
changeset 0 f72a12da539e
child 9 f966699dea19
child 40 9f778a73d522
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/nativeuicontroller/src/appui.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,706 @@
+/*
+* Copyright (c) 2007-2007 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: 
+*
+*/
+
+
+#include "appui.h"
+#include "ainativeui.hrh"
+#include "ainativeuistrings.h" // string literals
+#include "ainativeuiview.h"
+#include "application.h"
+#include "nativeuicontroller.h"
+#include "aiuiframeworkobserver.h"
+#include "aifweventhandler.h"
+#include <AiNativeUi.rsg>
+
+#include "aipropertyextension.h"
+#include "aicontentmodel.h"
+#include "aiuiidleintegration.h"
+#include "activeidle2domaincrkeys.h"
+#include "activeidle2domainpskeys.h"
+#include "extrstandbycontainerif.h"
+#include "debug.h"
+
+#include <startupdomainpskeys.h>
+#include <aipspropertyobserver.h>
+#include <centralrepository.h>
+#include <e32base.h>
+#include <e32property.h>
+#include <avkon.rsg>                    // for status pane layout resource ids
+#include <eikon.hrh>
+#include <bautils.h>
+#include <ecom/implementationproxy.h>
+#include <data_caging_path_literals.hrh>
+#include <ConeResLoader.h>
+#include <featmgr.h>
+#include <avkondomainpskeys.h>
+#include <AknUtils.h>
+#include <layoutmetadata.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+namespace
+    {
+    _LIT( KResourceDrive, "Z:" );
+    _LIT( KResourceFile, "ainativeui.rsc" );
+    #define KResourcePath KDC_APP_RESOURCE_DIR
+
+    const TInt KDefaultStatusPaneLayout = R_AVKON_STATUS_PANE_LAYOUT_IDLE;
+
+    //
+    // Get status pane configuration from cenrep
+    //
+    TInt GetLayoutCenrep()
+        {
+        TInt value = EAiStatusPaneLayoutIdleNormal;
+        TUid uid = { KCRUidActiveIdleLV };
+        CRepository* cenRep = CRepository::NewLC( uid );
+        cenRep->Get( KAiStatusPaneLayout, value );
+        CleanupStack::PopAndDestroy( cenRep );
+        return value;
+        }
+
+    //
+    // Resolves status pane layout for CXnAppUiAdapter::ConstructL()
+    //
+    TInt StatusPaneLayoutResourceIdL( TInt aLayoutId )
+        {
+        TInt layout = aLayoutId;
+        switch( aLayoutId )
+            {
+            case EAiStatusPaneLayoutIdleNormal:
+                {
+                layout = R_AVKON_STATUS_PANE_LAYOUT_IDLE;
+                break;
+                }
+            case EAiStatusPaneLayoutIdleFlat:
+                {
+                layout = R_AVKON_STATUS_PANE_LAYOUT_IDLE_FLAT;
+                break;
+                }
+            case EAiStatusPaneLayoutIdleHidden:
+                {
+                layout = KDefaultStatusPaneLayout;
+                break;
+                }
+            default:
+                {
+                break;
+                }
+            }
+        return layout;
+        }
+    
+    // -----------------------------------------------------------------------------
+    // 
+    // Calculate touch sensitive softkey area for Top button (landscape)
+    // -----------------------------------------------------------------------------         
+    TRect SoftkeyRectTopTouch()
+        {
+        TRect screen;
+        AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+        TAknLayoutRect layoutRect;
+
+        TAknWindowComponentLayout rightAreaLayout(
+                AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+
+        layoutRect.LayoutRect( screen, TAknWindowComponentLayout::Compose( rightAreaLayout,
+                AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() );
+        TRect topSKRect( layoutRect.Rect() );
+        
+        layoutRect.LayoutRect( topSKRect, 
+                        AknLayoutScalable_Avkon::aid_touch_sctrl_top().LayoutLine() );
+        return layoutRect.Rect();
+        }
+
+    // -----------------------------------------------------------------------------
+    // 
+    // Calculate touch sensitive softkey area for right button (portrait)
+    // -----------------------------------------------------------------------------         
+    TRect SoftkeyRectRightTouch()
+        {
+        TRect screen;
+        AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+        TAknLayoutRect layoutRect;
+
+        TAknWindowComponentLayout bottomAreaLayout(
+                AknLayoutScalable_Avkon::area_bottom_pane( 0 ) );
+
+
+        layoutRect.LayoutRect( screen, TAknWindowComponentLayout::Compose( bottomAreaLayout,
+                AknLayoutScalable_Avkon::control_bg_pane() ).LayoutLine() );
+        TRect rightSKRect( layoutRect.Rect() );
+        layoutRect.LayoutRect(
+                rightSKRect,
+                AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+        return layoutRect.Rect();
+        }
+
+    
+    }
+
+using namespace AiNativeUiController;
+
+// ========== MEMBER FUNCTIONS ================================================
+
+CAppUi::CAppUi(CNativeUiController* aUiCtl)
+    : iUiCtl(aUiCtl)
+    {
+    }
+
+void CAppUi::ConstructL()
+    {
+    BaseConstructL(EAknEnableSkin|EAknEnableMSK/*|ENoAppResourceFile*/);
+
+    // Disable CCoeEnv exit checks.
+    // Active Idle Framework will perform the checks.
+    iCoeEnv->DisableExitChecks(ETrue);
+
+    if( !iResourceLoader )
+        {
+        iResourceLoader = new(ELeave) RConeResourceLoader( *iCoeEnv );
+
+        // 1) Load resources file for resource publishing
+        TFullName resourceFile( KResourceDrive );
+        resourceFile.Append( KResourcePath );
+        resourceFile.Append( KResourceFile );
+        BaflUtils::NearestLanguageFile( iCoeEnv->FsSession(), resourceFile );
+
+        iResourceLoader->OpenL( resourceFile );
+        }
+
+    iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+    if( !iUiCtl )
+        {
+        User::Leave(KErrNotFound);
+        return; // for lint
+        }
+
+    iFwEventHandler = iUiCtl->FwEventHandler();
+
+    iUiFwObserver = iUiCtl->UiFrameworkObserver();
+
+    TAiIdleKeySoundConfig keySoundConfig;
+    keySoundConfig.iKeySounds = KeySounds();
+    keySoundConfig.iContextResId = R_NATIVEUI_DEFAULT_SKEY_LIST;
+    iIdleIntegration = CAiUiIdleIntegration::NewL
+        ( *iEikonEnv, keySoundConfig, iFwEventHandler );
+
+    iUiCtl->SetAppUi( this );
+
+    if( iFwEventHandler )
+        {
+        iFwEventHandler->AppEnvReadyL();
+        }
+    TBool isFullScreen = EFalse;
+    //Get pointer to status pane
+    CEikStatusPane* statusPane = static_cast<CAknAppUi*>( iEikonEnv->EikAppUi() )->StatusPane();
+    if( statusPane )
+        {
+        // Update status pane layout ot the correct one.
+        TInt statusPaneLayout = GetLayoutCenrep();
+        iCurrentStatusPaneLayout = StatusPaneLayoutResourceIdL( statusPaneLayout );
+
+        TInt id = statusPane->CurrentLayoutResId();
+        if( id != iCurrentStatusPaneLayout &&
+            id != R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT )
+            {
+            statusPane->SwitchLayoutL( iCurrentStatusPaneLayout );
+            }
+        else
+            {
+            iCurrentStatusPaneLayout = id;
+            }
+
+        if( statusPaneLayout == EAiStatusPaneLayoutIdleHidden &&
+            iCurrentStatusPaneLayout != R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT  )
+            {
+            statusPane->MakeVisible( EFalse );
+            isFullScreen = ETrue;
+            }
+        else
+            {
+            statusPane->MakeVisible( ETrue );
+            }
+        statusPane->ApplyCurrentSettingsL();
+        statusPane->DrawNow();
+        }
+
+    iAppView = CAiNativeUiView::NewL( ClientRect(), this );
+    iAppView->SetMopParent(this);
+    RegisterViewL( *iAppView );
+    AddToStackL( iAppView );
+    
+    // Reset softkey locked indications. Error may be ignored - not defined would be typical.
+    RProperty::Define( KPSUidAiInformation, KActiveIdleExtHS_LSKLocked, RProperty::EText );
+    RProperty::Set( KPSUidAiInformation, KActiveIdleExtHS_LSKLocked, KNullDesC );
+    RProperty::Define( KPSUidAiInformation, KActiveIdleExtHS_RSKLocked, RProperty::EText );
+    RProperty::Set( KPSUidAiInformation, KActiveIdleExtHS_RSKLocked, KNullDesC );
+    RProperty::Define( KPSUidAiInformation, KActiveIdleExtHS_PluginConfChange, RProperty::EInt );
+    RProperty::Set( KPSUidAiInformation, KActiveIdleExtHS_PluginConfChange, 0 );
+    
+    const TUid KCAIPluginContainerImplementationUid = { 0x101FD658 };
+
+    iStanbyContainerIF = CExtrStandbyContainerIF::NewL( KCAIPluginContainerImplementationUid,
+                                         iAppView );
+    iStanbyContainerIF->SetRect( ClientRect() );
+    iStanbyContainerIF->SetFullScreenMode( isFullScreen );
+    iAppView->SetControl( iStanbyContainerIF );
+
+    iAIRepository = CRepository::NewL( TUid::Uid( KCRUidActiveIdleLV ) );
+    // CenRep notifier to listen statuspane key changes in cenrep.
+    iNotifyHandler = CCenRepNotifyHandler::NewL( *this,
+                                                 *iAIRepository,
+                                                 CCenRepNotifyHandler::EIntKey,
+                                                 KAiStatusPaneLayout );
+    iNotifyHandler->StartListeningL();
+
+    if( iFwEventHandler )
+        {
+        iFwEventHandler->HandleUiReadyEventL(*iUiCtl);
+        }
+
+    // Check powerkey availability
+    FeatureManager::InitializeLibL();
+    iFeatureNoPowerKey =
+        FeatureManager::FeatureSupported( KFeatureIdNoPowerkey );
+    FeatureManager::UnInitializeLib();
+
+    if(iFeatureNoPowerKey)
+        {
+        iPowerkeyStatusObserver = AiUtility::CreatePSPropertyObserverL(
+                                    TCallBack( HandlePowerkeyEvent, this ),
+                                    KPSUidAvkonDomain,
+                                    KAknEndKeyEvent );
+        }
+
+    CAknAppUiBase::SetKeyEventFlags( CAknAppUiBase::EDisableSendKeyShort |
+                                     CAknAppUiBase::EDisableSendKeyLong );
+    }
+
+CAppUi* CAppUi::NewL(CNativeUiController* aUiCtl)
+    {
+    CAppUi* self = new (ELeave) CAppUi(aUiCtl );
+
+    // ConstructL is called by the UI framework
+
+    return self;
+    }
+
+CAppUi::~CAppUi()
+    {
+    Release( iPowerkeyStatusObserver );
+    delete iTimer;
+    delete iNotifyHandler;
+    delete iAIRepository;
+    delete iStanbyContainerIF;
+    delete iIdleIntegration;
+    TRAP_IGNORE( DeactivateActiveViewL() );
+    if( iAppView )
+        {
+        DeregisterView( *iAppView );
+        RemoveFromStack( iAppView );
+        delete iAppView;
+        }
+    if( iResourceLoader )
+        {
+        iResourceLoader->Close();
+        delete iResourceLoader;
+        }
+    }
+
+void CAppUi::HandleForegroundEventL(TBool aForeground)
+    {
+    CAknAppUi::HandleForegroundEventL( aForeground );
+
+    if ( iUiFwObserver )
+        {
+        iUiFwObserver->HandleForegroundEvent( aForeground );
+        }
+    }
+
+void CAppUi::HandleCommandL(TInt aCommand)
+    {
+    switch (aCommand)
+        {
+        case EEikCmdExit:
+            {
+            TInt value;
+            TInt err = RProperty::Get( KPSUidStartup, KPSGlobalSystemState, value );
+            if( err == KErrNone )
+                {
+                if ( value == ESwStateShuttingDown )
+                    {
+                    // If all is ok we filter our exits
+                    Exit();
+                    }
+                }
+            else
+                {
+                // If all is not ok we still exit
+                Exit();
+                }
+            break;
+            }
+        case EAknSoftkeyExit:
+        case EAknCmdExit: // fallthrough
+            {
+
+#ifdef _DEBUG
+
+            Exit();
+            if( iFwEventHandler && iUiCtl )
+                {
+                iFwEventHandler->HandleUiShutdown( *iUiCtl );
+                }
+            break;
+
+#endif // _DEBUG
+
+            }
+
+        case ENativeUiSoftkeyLeft:
+            {
+            if( iFwEventHandler ) // LSK
+                {
+                HBufC* appBuf;
+                appBuf = HBufC::NewLC( RProperty::KMaxPropertySize );
+                TPtr appPtr = appBuf->Des();
+                RProperty::Get( KPSUidAiInformation, KActiveIdleExtHS_LSKLocked, appPtr );
+                if( appPtr.Length() > 0 )
+                    {
+                    iFwEventHandler->HandlePluginEvent(KAiLskLaunchByIndexLocked);
+                    }
+                else
+                    {
+                    iFwEventHandler->HandlePluginEvent(KAiLskLaunchByIndex);
+                    }
+                CleanupStack::PopAndDestroy( appBuf );
+                }
+            break;
+            }
+
+        case ENativeUiSoftkeyRight:
+            {
+            break;
+            }
+
+        case ENativeUiSelectionKey:
+            {
+            if( iAppView )
+                {
+                TKeyEvent keyEvent;
+                keyEvent.iCode = EKeyOK;
+                keyEvent.iRepeats = 0;
+                TEventCode type(EEventKey);
+                iAppView->OfferKeyEventL(keyEvent, type);
+                }
+            break;
+            }
+
+        default:
+            {
+            break;
+            }
+
+        }
+
+    }
+
+void CAppUi::HandleResourceChangeL(TInt aType)
+    {
+    CAknAppUi::HandleResourceChangeL(aType);
+
+    if( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        // Screen layout changed, update and draw status pane.
+        //Get pointer to status pane
+        CEikStatusPane* statusPane = static_cast<CAknAppUi*>( iEikonEnv->EikAppUi() )->StatusPane();
+        if( statusPane )
+            {
+            // Update status pane layout ot the correct one.
+            TInt statusPaneLayout = GetLayoutCenrep();
+            TInt id = statusPane->CurrentLayoutResId();
+            if( id != iCurrentStatusPaneLayout )
+                {
+                statusPane->SwitchLayoutL( id );
+                iCurrentStatusPaneLayout = id;
+                }
+            if( statusPaneLayout == EAiStatusPaneLayoutIdleHidden &&
+                id != R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT )
+                {
+                statusPane->MakeVisible( EFalse );
+                iStanbyContainerIF->SetFullScreenMode( ETrue );
+                }
+            else
+                {
+                statusPane->MakeVisible( ETrue );
+                iStanbyContainerIF->SetFullScreenMode( EFalse );
+                }
+            statusPane->ApplyCurrentSettingsL();
+            statusPane->DrawNow();
+            }
+        if( iAppView )
+            {
+            iAppView->SetRect( ClientRect() );
+            iAppView->DrawNow();
+            }
+
+        }
+
+    if ( iUiFwObserver )
+        {
+        iUiFwObserver->HandleResourceChange(aType);
+        }
+    }
+
+void CAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
+    {
+    // Pointer event handling for RSK and SIND launching  
+    // LSK handled via HandleCommand
+    if ( AknLayoutUtils::PenEnabled() && aEvent.Type() == EEventPointer )
+        {
+        TPointerEvent *event = aEvent.Pointer();
+        HandlePointerEvent( *event );
+        }
+
+    if( iIdleIntegration )
+        {
+        // Forward window server events first to idle integration library
+        iIdleIntegration->HandleWsEventL(aEvent, aDestination);
+        }
+
+    // Call base class to let the UI framework handle the event
+    CAknAppUi::HandleWsEventL( aEvent, aDestination);
+    }
+
+void CAppUi::HandlePointerEvent( TPointerEvent &aEvent )
+    {        
+    if ( !Cba()->IsVisible() )
+        {
+        return;
+        }
+
+    TRect rskRect;
+    if ( Layout_Meta_Data::IsLandscapeOrientation() )
+        {
+        rskRect = ::SoftkeyRectTopTouch();
+        }
+    else
+        {
+        rskRect = ::SoftkeyRectRightTouch();
+        }
+    // pointer event done in RSK => activate sind timer.
+    if ( aEvent.iType == TPointerEvent::EButton1Down && 
+            rskRect.Contains( aEvent.iParentPosition )) 
+        {              
+        iSINDKeyDown = ETrue;         
+        const TTimeIntervalMicroSeconds32 KLongKeyPress(600000);
+        iTimer->Cancel();
+        iTimer->Start( KLongKeyPress, 0, TCallBack( TimerDone, this ) );
+        }
+    // It doesn't matter where the button up is done 
+    // the voice dial is still skipped
+    else if ( iSINDKeyDown && 
+            aEvent.iType == TPointerEvent::EButton1Up )
+        {
+        SkipVoiceDial();
+        }
+    // Dragging outside RSK cancels opening of shortcut
+    // and voice dial
+    else if ( iSINDKeyDown && 
+            aEvent.iType == TPointerEvent::EDrag &&
+            !rskRect.Contains( aEvent.iParentPosition ))
+        {
+        iTimer->Cancel();
+        iSINDKeyDown = EFalse;
+        }
+    }
+
+void CAppUi::HandleScreenDeviceChangedL()
+    {
+    CAknAppUi::HandleScreenDeviceChangedL();
+
+    if ( iFwEventHandler && iUiCtl )
+        {
+        //iFwEventHandler->HandleUiLayoutChangeL(*iUiCtl);
+        }
+    }
+
+void CAppUi::PrepareToExit()
+    {
+    if ( iFwEventHandler && iUiCtl )
+        {
+        iUiCtl->PrepareToExit();
+        iFwEventHandler->HandleUiShutdown(*iUiCtl);
+        }
+    }
+
+TKeyResponse CAppUi::HandleKeyEventL(
+    const TKeyEvent& aKeyEvent,
+    TEventCode aType )
+    {
+    if( aKeyEvent.iScanCode == EStdKeyDevice1 )
+        {
+        if( aType == EEventKeyDown )
+            {
+            iSINDKeyDown = ETrue;
+            const TTimeIntervalMicroSeconds32 KLongKeyPress(600000);
+            iTimer->Cancel();
+            iTimer->Start( KLongKeyPress, 0, TCallBack( TimerDone, this ) );
+            }
+        else if( aType == EEventKeyUp )
+            {
+            if( iSINDKeyDown )
+                {
+                SkipVoiceDial();
+                }
+            }
+        return EKeyWasConsumed;
+        }
+    else
+        {
+        if( aType == EEventKeyDown && iSINDKeyDown )
+            {
+            iSINDKeyDown = EFalse;
+            SkipVoiceDial();
+            }
+        if( iAppView )
+            {
+            return iAppView->OfferKeyEventL(aKeyEvent, aType);
+            }
+        }
+
+    return EKeyWasNotConsumed;
+    }
+
+void CAppUi::SkipVoiceDial()
+    {
+    iTimer->Cancel();
+    // Handle skip scenario only if voice dial ui hasn't been launched
+    if ( iFwEventHandler )
+        {
+        HBufC* app2Buf;
+        app2Buf = HBufC::New( RProperty::KMaxPropertySize );
+        if ( app2Buf )
+            {
+            TPtr app2Ptr = app2Buf->Des();
+            RProperty::Get( KPSUidAiInformation, KActiveIdleExtHS_RSKLocked, app2Ptr );
+            if( app2Ptr.Length() > 0 )
+                {
+                iFwEventHandler->HandlePluginEvent(KAiRskLaunchByIndexLocked);
+                }
+            else
+                {
+                iFwEventHandler->HandlePluginEvent(KAiRskLaunchByIndex);
+                }
+            delete app2Buf;
+            }
+    	}
+    iSINDKeyDown = EFalse;
+    }
+
+TInt CAppUi::TimerDone(TAny* aSelf)
+    {
+    CAppUi* self = static_cast<CAppUi*>( aSelf );
+    if ( self )
+        {
+        self->iTimer->Cancel();
+        self->iSINDKeyDown = EFalse;
+        self->iFwEventHandler->HandlePluginEvent(KAiRskLaunchVoiceDial);
+        }
+    return KErrNone;
+    }
+
+void CAppUi::StartL()
+    {
+    if( iStanbyContainerIF )
+        {
+        iStanbyContainerIF->StartL();
+        }
+    }
+
+void CAppUi::HandleNotifyInt( TUint32 aId, TInt aNewValue )
+    {
+    // Set status pane on the fly.
+    if( aId == KAiStatusPaneLayout )
+        {
+        if( aNewValue == EAiStatusPaneLayoutIdleNormal ||
+            aNewValue == EAiStatusPaneLayoutIdleFlat ||
+            aNewValue == EAiStatusPaneLayoutIdleHidden )
+            {
+            //Get pointer to status pane
+            CEikStatusPane* statusPane = static_cast<CAknAppUi*>( iEikonEnv->EikAppUi() )->StatusPane();
+            if( statusPane )
+                {
+                // Update status pane layout ot the correct one.
+                if( aNewValue == EAiStatusPaneLayoutIdleHidden &&
+                    iCurrentStatusPaneLayout != R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT  )
+                    {
+                    statusPane->MakeVisible( EFalse );
+                    if ( iStanbyContainerIF )
+                        {
+                        iStanbyContainerIF->SetFullScreenMode( ETrue );
+                        }
+
+                    }
+                else
+                    {
+                    statusPane->MakeVisible( ETrue );
+                    if ( iStanbyContainerIF )
+                        {
+                        iStanbyContainerIF->SetFullScreenMode( EFalse );
+                        }
+                    }
+                statusPane->DrawNow();
+                if( iStanbyContainerIF )
+                    {
+                    iStanbyContainerIF->SetRect( ClientRect() );
+                    }
+                if ( iAppView )
+                    {
+                    iAppView->DrawNow();
+                    }
+
+                }
+            }
+        }
+    }
+    
+void CAppUi::ExtHSThemeChanged()
+    {
+    //TRAP_IGNORE( iFwEventHandler->HandleUiThemeChangeStartL( *iUiCtl ) );
+    TRAP_IGNORE( iFwEventHandler->HandleUiReadyEventL( *iUiCtl ) );
+    }
+
+TInt CAppUi::HandlePowerkeyEvent( TAny* aPtr )
+    {
+    CAppUi* self = static_cast<CAppUi*>(aPtr);
+    if( self && self->iStanbyContainerIF )
+        {
+        TKeyEvent keyEvent;
+        keyEvent.iCode = EKeyPhoneEnd;
+        TEventCode eventType;
+        eventType = EEventKey;
+        TRAP_IGNORE( self->iStanbyContainerIF->OfferKeyEventL( keyEvent, eventType ) );
+        }
+    return KErrNone;
+    }
+
+// End of File.