/*
* Copyright (c) 2006-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: Default key event handling of System Application
*
*/
#include <e32property.h>
#include <eikon.hrh>
#include <coemain.h>
#include <aknkeylock.h>
#include <AknTaskList.h>
#include <apgtask.h>
#include <apgcli.h>
#include <apgwgnam.h>
#include <apacmdln.h>
#include <AiwPoCParameters.h>
#include <AiwServiceHandler.h>
#include <featmgr.h>
#include <coreapplicationuisdomainpskeys.h>
#include <PSVariables.h>
#include <startupdomainpskeys.h>
#include <hwrmdomainpskeys.h>
#include <u32hal.h>
#include <SysAp.rsg>
#include <centralrepository.h> //for CRepository
#include <settingsinternalcrkeys.h>
#include <keylockpolicyapi.h>
#include <ctsydomainpskeys.h>
#include "sysapdefaultkeyhandler.h"
#include "sysapcallback.h"
#include "SysAp.hrh"
#include "AknSgcc.h"
const TInt KModifierMask( 0 );
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
// CSysApDefaultKeyHandler::CSysApDefaultKeyHandler
// ---------------------------------------------------------------------------
//
CSysApDefaultKeyHandler::CSysApDefaultKeyHandler( MSysapCallback& aCallback ) :
iCallback(aCallback),
iCameraSupported(EFalse),
iCoverDisplaySupported(EFalse),
iKeylock(NULL),
iCapturedEKeyCamera(0),
iCapturedEKeyTwistOpen(0),
iCapturedEKeyTwistClose(0),
iCapturedEKeyGripOpen(0),
iCapturedEKeyGripClose(0),
iCapturedEKeyPoC(0),
iAknUiServerConnected(EFalse)
{
}
// ---------------------------------------------------------------------------
// CSysApDefaultKeyHandler::ConstructL
// ---------------------------------------------------------------------------
//
void CSysApDefaultKeyHandler::ConstructL()
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::ConstructL()") ) );
RWindowGroup groupWin = CCoeEnv::Static()->RootWin();
User::LeaveIfError ( iCapturedEKeyCamera = groupWin.CaptureKey( EKeyCamera, KModifierMask, KModifierMask ) );
User::LeaveIfError ( iCapturedEKeyTwistOpen = groupWin.CaptureKey( EKeyTwistOpen, KModifierMask, KModifierMask ) );
User::LeaveIfError ( iCapturedEKeyTwistClose = groupWin.CaptureKey( EKeyTwistClose, KModifierMask, KModifierMask ) );
User::LeaveIfError ( iCapturedEKeyGripOpen = groupWin.CaptureKey( EKeyGripOpen, KModifierMask, KModifierMask ) );
User::LeaveIfError ( iCapturedEKeyGripClose = groupWin.CaptureKey( EKeyGripClose, KModifierMask, KModifierMask ) );
User::LeaveIfError ( iCapturedEKeyPoC = groupWin.CaptureKey( EKeyPoC, KModifierMask, KModifierMask ) );
// flip key events don't need to be captured, because in current setup they are not real events but simulated by SysAp
// according to notifications received from P&S key that stores flip information
FeatureManager::InitializeLibL();
iCameraSupported = FeatureManager::FeatureSupported( KFeatureIdCamera );
iCoverDisplaySupported = FeatureManager::FeatureSupported( KFeatureIdCoverDisplay );
FeatureManager::UnInitializeLib();
TKeyLockBuf lockBuf;
iCallback.ExecQueryL( MSysapCallback::EGetKeylock, lockBuf );
iKeylock = lockBuf();
iKeypadWasLocked = iKeylock->IsKeyLockEnabled();
__ASSERT_DEBUG( iKeylock, User::Panic( _L("CSysApDefaultKeyHandler::ConstructL: iKeylock not initialized"), KErrBadHandle ) );
if ( iCoverDisplaySupported ) // if flip status is monitored, set the initial flip status now
{
TInt flipValue;
TInt err = RProperty::Get( KPSUidHWRM, KHWRMFlipStatus, flipValue );
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::ConstructL: flipValue=%d, err=%d"), flipValue, err ) );
if ( err == KErrNone )
{
switch ( flipValue )
{
case EPSHWRMFlipOpen:
SetDisplayState( ETrue );
break;
case EPSHWRMFlipClosed:
SetDisplayState( EFalse );
break;
case EPSHWRMFlipStatusUninitialized:
default:
// set display state only if the current flip position is known
break;
}
}
}
//Load keylock slide handling CR
TRAP_IGNORE( iSlideRepository = CRepository::NewL( KCRUidSlideSettings ) );
iKeylockPolicy = CKeyLockPolicyApi::NewL( EPolicyActivateKeyguard );
//Load PhoneCallStatus P&S
TInt err = iCallStateProperty.Attach(KPSUidCtsyCallInformation, KCTsyCallState);
}
// ---------------------------------------------------------------------------
// CSysApDefaultKeyHandler::NewL
// ---------------------------------------------------------------------------
//
CSysApDefaultKeyHandler* CSysApDefaultKeyHandler::NewL( MSysapCallback& aCallback )
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::NewL()") ) );
CSysApDefaultKeyHandler* self = new( ELeave ) CSysApDefaultKeyHandler( aCallback) ;
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// CSysApDefaultKeyHandler::~CSysApDefaultKeyHandler
// ---------------------------------------------------------------------------
//
CSysApDefaultKeyHandler::~CSysApDefaultKeyHandler()
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::~CSysApDefaultKeyHandler()") ) );
iAknUiServer.Close();
RWindowGroup groupWin = CCoeEnv::Static()->RootWin();
groupWin.CancelCaptureKey( iCapturedEKeyCamera );
groupWin.CancelCaptureKey( iCapturedEKeyTwistOpen );
groupWin.CancelCaptureKey( iCapturedEKeyTwistClose );
groupWin.CancelCaptureKey( iCapturedEKeyGripOpen );
groupWin.CancelCaptureKey( iCapturedEKeyGripClose );
groupWin.CancelCaptureKey( iCapturedEKeyPoC );
delete iSlideRepository;
delete iKeylockPolicy;
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::HandleKeyEventL()
// ----------------------------------------------------------------------------
//
TKeyResponse CSysApDefaultKeyHandler::HandleKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::HandleKeyEventL: aKeyEvent.iCode=%d, aKeyEvent.iScanCode=%d, aType=%d"),
aKeyEvent.iCode, aKeyEvent.iScanCode, aType ) );
TKeyResponse response = EKeyWasNotConsumed;
__ASSERT_DEBUG( aType == EEventKey, User::Invariant() ); // other than event keys should not provided
if( aType == EEventKey )
{
response = EKeyWasConsumed; // set again in default case if not consumed
switch ( aKeyEvent.iCode )
{
case EKeyGripOpen:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyGripOpen") ) );
RProperty::Set( KPSUidHWRM, KHWRMGripStatus, EPSHWRMGripOpen );
iKeypadWasLocked = iKeylock->IsKeyLockEnabled();
iKeylockPolicy->DisableKeyguardFeature();
if (!IsDeviceLocked())
{
iCallback.ExecCommandL( MSysapCallback::EResetKeyguardState );
iKeylock->DisableKeyLock();
iCallback.ExecCommandL( MSysapCallback::ECancelPowermenu );
}
// apply default light control
iCallback.ExecCommandL( MSysapCallback::EUpdateLights, TUpdateLightsBuf(EKeyGripOpen) );
break;
case EKeyGripClose:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyGripClosed") ) );
RProperty::Set( KPSUidHWRM, KHWRMGripStatus, EPSHWRMGripClosed );
iKeylockPolicy->EnableKeyguardFeature();
iCallback.ExecCommandL( MSysapCallback::ECancelPowermenu );
if( !iSlideRepository )
{ // default behavior is to always ask for keylock
if ( !IsDeviceLocked() && UiReady() )
{
iKeylock->OfferKeyLock();
}
}
else
{ // keylock action is defined by user setting
TInt status(0);
TInt err = iCallStateProperty.Get( status );
if (err == KErrNone)
{
switch ( status )
{
case EPSCTsyCallStateUninitialized:
case EPSCTsyCallStateNone:
{
TInt keyGuardSetting;
iSlideRepository->Get( KSlideKeyguard, keyGuardSetting );
switch( ( TSlideSettingKeyguard ) keyGuardSetting )
{
case ESlideSettingsKeyguardActivatingOn:
iKeylock->EnableKeyLock();
break;
case ESlideSettingsKeyguardActivatingAskMe:
iKeylock->OfferKeyLock();
break;
case ESlideSettingsKeyguardActivatingOff:
//do nothing
break;
case ESlideSettingsKeyguardActivatingAutomatic:
if( iKeypadWasLocked )
{
iKeylock->EnableKeyLock();
}
break;
}
}
default: // any other state
break;
}
}
}
// apply default light control
iCallback.ExecCommandL( MSysapCallback::EUpdateLights, TUpdateLightsBuf(EKeyGripClose) );
break;
case EKeyFlipOpen: // simulated key event
{
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyFlipOpen") ) );
SetDisplayState( ETrue );
// apply default light control
iCallback.ExecCommandL( MSysapCallback::EUpdateLights, TUpdateLightsBuf(EKeyFlipOpen) );
}
break;
case EKeyFlipClose: // simulated key event
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyFlipClose") ) );
SetDisplayState( EFalse );
// apply default light control
iCallback.ExecCommandL( MSysapCallback::EUpdateLights, TUpdateLightsBuf(EKeyFlipClose) );
break;
case EKeyTwistOpen:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyTwistOpen") ) );
RProperty::Set( KPSUidHWRM, KHWRMTwistStatus, EPSHWRMTwistOpen );
break;
case EKeyTwistClose:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyTwistClose") ) );
RProperty::Set( KPSUidHWRM, KHWRMTwistStatus, EPSHWRMTwistClose );
break;
case EKeyCamera:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyCamera") ) );
if ( iCameraSupported && !IsDeviceLocked() && !DoShowKeysLockedNote() )
{
iCallback.ExecCommandL( MSysapCallback::ECancelPowermenu );
ActivateApplicationL( KSysApCamcorderUid );
}
break;
case EKeyPoC:
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::HandleKeyEventL: EKeyPoC") ) );
LaunchPocL();
break;
default:
response = EKeyWasNotConsumed;
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::CSysApDefaultKeyHandler: key was not consumed.") ) );
break;
}
}
return response;
}
#ifndef SYSAP_USE_STARTUP_UI_PHASE
// -----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::IsStateNormal()
// -----------------------------------------------------------------------------
//
TBool CSysApDefaultKeyHandler::IsStateNormal() const
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::IsStateNormal")) );
TInt state;
TInt errorCode = RProperty::Get( KPSUidStartup, KPSGlobalSystemState, state );
if ( errorCode == KErrNone )
{
return state == ESwStateNormalRfOn ||
state == ESwStateNormalRfOff ||
state == ESwStateNormalBTSap;
}
else
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::IsStateNormal: Failed to read global system state, error code %d." ), errorCode ) );
return EFalse;
}
}
#endif // SYSAP_USE_STARTUP_UI_PHASE
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::UiReady()
//
// ----------------------------------------------------------------------------
TBool CSysApDefaultKeyHandler::UiReady() const
{
#ifdef SYSAP_USE_STARTUP_UI_PHASE
TInt state( 0 );
TInt err = RProperty::Get( KPSUidStartup, KPSGlobalSystemState, state );
if ( err != KErrNone || state == ESwStateEmergencyCallsOnly ) // emergency calls only state must block UI operations
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::UiReady: KPSGlobalSystemState=%d, err=%d." ), state, err ) );
return EFalse;
}
err = RProperty::Get( KPSUidStartup, KPSStartupUiPhase, state );
if ( err != KErrNone )
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::UiReady: Failed to read KPSStartupUiPhase, err=%d." ), err ) );
return EFalse;
}
return state == EStartupUiPhaseAllDone;
#else // SYSAP_USE_STARTUP_UI_PHASE
// if KPSSStartupUiPhase is not used, global system state normal is handled as UI idle state
return IsStateNormal();
#endif // SYSAP_USE_STARTUP_UI_PHASE
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::ActivateApplicationL()
// ----------------------------------------------------------------------------
//
void CSysApDefaultKeyHandler::ActivateApplicationL( const TUid aUid ) const
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::ActivateApplicationL") ) );
// Applications must not be activated before reaching normal system operation state
if ( UiReady() )
{
CAknTaskList* apaTaskList = CAknTaskList::NewL( CCoeEnv::Static()->WsSession() );
TApaTask apaTask = apaTaskList->FindRootApp( aUid ); // only root application should not be activated
delete apaTaskList;
if ( apaTask.Exists() )
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::ActivateApplicationL: application brought to foreground") ) );
#ifdef _DEBUG
// camery latency measurement environment instrumentation, don't remove
if ( aUid == KSysApCamcorderUid )
{
TRACES( RDebug::Print( _L("e_CAM_PRI_OFF_TO_ON 1") ) );
}
#endif // _DEBUG
CAknSgcClient::MoveApp ( apaTask.WgId(), ESgcMoveAppToForeground );
}
else
{
TInt err( KErrNone );
TApaAppInfo appInfo;
RApaLsSession apaLsSession;
User::LeaveIfError( apaLsSession.Connect() );
CleanupClosePushL( apaLsSession );
err = apaLsSession.GetAppInfo( appInfo, aUid );
if ( !err )
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::ActivateApplicationL: starting application") ) );
CApaCommandLine* apaCommandLine = CApaCommandLine::NewLC();
apaCommandLine->SetExecutableNameL( appInfo.iFullName );
apaCommandLine->SetCommandL( EApaCommandRun );
#ifdef _DEBUG
// camery latency measurement environment instrumentation, don't remove
if ( aUid == KSysApCamcorderUid )
{
TRACES( RDebug::Print( _L("e_CAM_PRI_OFF_TO_ON 1") ) );
}
#endif // _DEBUG
apaLsSession.StartApp( *apaCommandLine );
CleanupStack::PopAndDestroy( apaCommandLine );
}
else
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::ActivateApplicationL err=%d"), err ) );
}
// pop and destroy will also close this session
CleanupStack::PopAndDestroy( &apaLsSession );
}
}
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::LaunchPocL()
// ----------------------------------------------------------------------------
//
void CSysApDefaultKeyHandler::LaunchPocL()
{
TRACES( RDebug::Print(_L("CSysApDefaultKeyHandler::LaunchPocL") ) );
if ( UiReady() && !IsDeviceLocked() && !DoShowKeysLockedNote() )
{
CAiwServiceHandler* serviceHandler = CAiwServiceHandler::NewLC();
serviceHandler->AttachL( R_POC_AIW_INTEREST );
CAiwGenericParamList* inParams = CAiwGenericParamList::NewLC();
inParams->AppendL(TAiwGenericParam( EGenericParamPoCLaunchView, TAiwVariant(EAiwPoCMainView)));
serviceHandler->ExecuteServiceCmdL( KAiwCmdPoC, *inParams, serviceHandler->OutParamListL());
CleanupStack::PopAndDestroy( inParams );
CleanupStack::PopAndDestroy( serviceHandler);
}
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::IsDeviceLocked()
// ----------------------------------------------------------------------------
TBool CSysApDefaultKeyHandler::IsDeviceLocked() const
{
TInt value(0);
TBool retval(EFalse);
RProperty::Get( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, value );
if ( value > EAutolockOff )
{
retval = ETrue;
}
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::IsDeviceLocked()=%d" ), retval ) );
return retval;
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::SetDisplayState
// ----------------------------------------------------------------------------
void CSysApDefaultKeyHandler::SetDisplayState( TBool aFlipOpen ) const
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::SetDisplayState: aFlipOpen=%d" ), aFlipOpen ) );
if ( iCoverDisplaySupported )
{
// Turn on/off the main display
TInt err = UserSvr::HalFunction(EHalGroupDisplay, EDisplayHalSetState, (TAny*)aFlipOpen, NULL);
if ( err == KErrNone )
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::SetDisplayState: Main display state set: %d" ), aFlipOpen ) );
}
else
{
TRACES( RDebug::Print( _L( "CSysApDefaultKeyHandler::SetDisplayState: Main display state set failed: %d." ), err ) );
}
}
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::DoShowKeysLockedNote
// ----------------------------------------------------------------------------
//
TBool CSysApDefaultKeyHandler::DoShowKeysLockedNote()
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::DoShowKeysLockedNote: iAknUiServerConnected=%d"), iAknUiServerConnected ) );
TInt err(KErrNone);
if ( !iAknUiServerConnected )
{
err = iAknUiServer.Connect();
if ( err != KErrNone )
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::DoShowKeysLockedNote: RAknUiServer::Connect failed, err=%d"), err ) );
return ETrue; // assume that keypad/device is locked
}
iAknUiServerConnected = ETrue;
}
TBool keysLocked;
err = iAknUiServer.ShowKeysLockedNote( keysLocked );
if ( err != KErrNone )
{
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::DoShowKeysLockedNote: RAknUiServer::ShowKeysLockedNote failed, err=%d"), err ) );
keysLocked = ETrue; // assume that keypad/device is locked
}
return keysLocked;
}
// ----------------------------------------------------------------------------
// CSysApDefaultKeyHandler::IsDeviceModeKey
// ----------------------------------------------------------------------------
//
TBool CSysApDefaultKeyHandler::IsDeviceModeKey( const TKeyEvent& aKeyEvent )
{
TBool response( EFalse );
switch ( aKeyEvent.iCode )
{
case EKeyGripOpen:
case EKeyGripClose:
case EKeyFlipOpen:
case EKeyFlipClose:
case EKeyTwistOpen:
case EKeyTwistClose:
response = ETrue;
break;
default:
break; // not a device mode key
}
TRACES( RDebug::Print( _L("CSysApDefaultKeyHandler::IsDeviceModeKey: aKeyEvent.iCode=%d, response=%d"), aKeyEvent.iCode, response ) );
return response;
}