diff -r 000000000000 -r f72a12da539e idlehomescreen/nativeuicontroller/src/appui.cpp --- /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 + +#include "aipropertyextension.h" +#include "aicontentmodel.h" +#include "aiuiidleintegration.h" +#include "activeidle2domaincrkeys.h" +#include "activeidle2domainpskeys.h" +#include "extrstandbycontainerif.h" +#include "debug.h" + +#include +#include +#include +#include +#include +#include // for status pane layout resource ids +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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( 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( 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( 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( 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(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.