/*
* Copyright (c) 2002-2010 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: Avkon KeyLock Notifier
*
*/
#include "AknKeyLockNotifier.h"
#include <aknnotpi.rsg>
#include <eikenv.h>
#include <eikappui.h>
#include <apgwgnam.h>
#include <aknsoundsystem.h>
#include <avkon.rsg>
#include <eikkeysound.h>
#include <bautils.h>
#include <featmgr.h>
#include <AknTasHook.h>
#include <AknUtils.h>
#include <eikcba.h>
#include <aknnotecontrol.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <secondarydisplay/AknSecondaryDisplayDefs.h>
#include <avkondomainpskeys.h> // KPSUidAvkonDomain, KAknKeyguardStatus, TAknKeyguardStatus
#include <startupdomainpskeys.h> // KStartupSecurityCodeQueryStatus
#include <coreapplicationuisdomainpskeys.h> // KCoreAppUIsAutolockStatus
#include <AknNotifySignature.h>
#include "AknCapServerEntry.h"
#include <aknglobalpopupprioritycontroller.h>
#include "GlobalWindowPriorities.h"
#include <keylockpolicyapi.h>
#include <ScreensaverInternalPSKeys.h>
#include <PSVariables.h> // Property values
#include <coreapplicationuisdomainpskeys.h>
#include <startupdomainpskeys.h>
#include <ctsydomainpskeys.h>
#include <bafindf.h>
#include "AknNotifyPlugin.hrh"
#ifdef _DEBUG
#define TRACES(x) x
#else
#define TRACES(x)
#endif
/** Autolock application UID. */
const TUid KAutolockUid = { 0x100059B5 };
/** SysAp application UID. */
const TUid KSysApUid = { 0x100058F3 };
const TInt KAknObserverListGranularity = 4;
/** Timeout for the "offer keylock" note. */
const TInt KAknOfferKeyLockTimeout = 6000000; // 6sec
/** Command ID for note focus lost. */
const TInt KNoteCmdFocusLost = 3100;
// Asterisk key code for the keylock.
const TUint KAknAsterisk = '*';
const TUint KAknChineseAsterisk = 0xFF0A;
// Timeout defined in Keylock UI spesification.
// Custom value since Avkon note TTimeout values
// don't support 1 second timeout
const TInt KKeyLockCustomShortTimeout = 1000000;
// Timeout for display locked note
const TInt KKeyLockDisplayLockedTimeout = 3000000;
_LIT( KRESOURCEFILE, "\\resource\\aknnotpi.rsc" );
_LIT_SECURITY_POLICY_C1( KWritePolicy, ECapabilityWriteDeviceData );
/**
* CAknKeylockScreenSaverObserver captures primary keys
* from screensaver when screen saver is active.
*
* @lib aknoldstylenotif.lib
* @since 3.2
*/
NONSHARABLE_CLASS( CAknKeylockScreenSaverObserver ): public CActive
{
public:
/**
* Creates instance of the CAknKeylockScreenSaverObserver class.
*
* @param aWindowGroup application window group used to capture primary keys
* @return Returns the instance just created.
*/
static CAknKeylockScreenSaverObserver* NewL( RWindowGroup& aWindowGroup );
/**
* Destructor.
*/
~CAknKeylockScreenSaverObserver();
public:
/**
* Starts asynchronic listening KUidCurrentCall event
*
* @return KErrNone: if no errors
* @return KErrInUse: if already listening
*/
TInt Start();
/**
* Stops asynchronic listening KUidAutolockStatus event
*/
void Stop();
public:
/**
* Method handles the lock state changes.
*
* @param aStatus The new lock state
*/
void SetLockStatus( TBool aKeylockEnabled, TBool aAutolockEnabled );
private: // constructors
/**
* C++ default constructor.
*
* @param aAppUi (pointer to autolock appui)
*/
CAknKeylockScreenSaverObserver( RWindowGroup& aWindowGroup );
/**
* Symbian OS constructor.
*/
void ConstructL();
private: // from CActive
/** @see CActive::RunL() */
void RunL();
/** @see CActive::DoCancel() */
void DoCancel();
private:
/**
* Used to capture primary keys defined in keylocking policies
*/
void CapturePrimaryKeys( TBool aCapture );
private: // data
// screen saver on property
RProperty iScreenSaverActiveProperty;
// if screensaver is active or not
TBool iScreenSaverActive;
// if primary keys have been captured
TBool iCaptured;
// locking states
TBool iKeylockEnabled;
TBool iAutolockEnabled;
// left softkey capture
TInt iLeftSoftKey;
// a reference to application window group
RWindowGroup& iWindowGroup;
// keylockpolicy support (not owned)
CKeyLockPolicyApi* iUnlockPolicyApi;
// keylockpolicy support (not owned)
CKeyLockPolicyApi* iDevicelockPolicyApi;
// primary key captures
RArray<TUint> iPrimaryKeyCaptures;
};
// ===========================================================================
// class CAknKeylockScreenSaverObserver
// ===========================================================================
// ---------------------------------------------------------------------------
// Constructs a new entry with given values.
// ---------------------------------------------------------------------------
//
CAknKeylockScreenSaverObserver* CAknKeylockScreenSaverObserver::NewL(
RWindowGroup& aWindowGroup )
{
CAknKeylockScreenSaverObserver* self =
new (ELeave) CAknKeylockScreenSaverObserver( aWindowGroup );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAknKeylockScreenSaverObserver::~CAknKeylockScreenSaverObserver()
{
Cancel();
// Close the property handle.
iScreenSaverActiveProperty.Close();
// Release key captures.
CapturePrimaryKeys( EFalse );
// Delete policies.
delete iUnlockPolicyApi;
delete iDevicelockPolicyApi;
}
// ---------------------------------------------------------------------------
// Starts listening to the KScreenSaverOn event.
// ---------------------------------------------------------------------------
//
TInt CAknKeylockScreenSaverObserver::Start()
{
if ( IsActive() )
{
return KErrInUse;
}
iStatus = KRequestPending;
iScreenSaverActiveProperty.Subscribe( iStatus );
SetActive();
return KErrNone;
}
// ---------------------------------------------------------------------------
// Stops listening to the KScreenSaverOn event.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::Stop()
{
if ( !IsActive() )
{
return;
}
Cancel();
iScreenSaverActiveProperty.Cancel();
}
// ---------------------------------------------------------------------------
// C++ constructor
// ---------------------------------------------------------------------------
//
CAknKeylockScreenSaverObserver::CAknKeylockScreenSaverObserver(
RWindowGroup& aWindowGroup )
: CActive( 0 ),
iScreenSaverActive( EFalse ),
iCaptured( EFalse ),
iKeylockEnabled( EFalse ),
iAutolockEnabled( EFalse ),
iLeftSoftKey( NULL ),
iWindowGroup( aWindowGroup )
{
}
// ---------------------------------------------------------------------------
// Second phase constructor.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::ConstructL()
{
// Add this active object to the scheduler.
CActiveScheduler::Add( this );
User::LeaveIfError( iScreenSaverActiveProperty.Attach( KPSUidScreenSaver,
KScreenSaverOn ) );
// We need policies to poll primary keys.
iUnlockPolicyApi = CKeyLockPolicyApi::NewL( EPolicyDeactivateKeyguard );
if ( !iUnlockPolicyApi->HasConfiguration() )
{
delete iUnlockPolicyApi;
iUnlockPolicyApi = NULL;
}
// we need policies to poll primary keys
iDevicelockPolicyApi = CKeyLockPolicyApi::NewL( EPolicyDevicelockQuery );
if ( !iDevicelockPolicyApi->HasConfiguration() )
{
delete iDevicelockPolicyApi;
iDevicelockPolicyApi = NULL;
}
}
// ---------------------------------------------------------------------------
// From base class CActive.
// Handles change in the screen saver state.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::RunL()
{
if ( iKeylockEnabled || iAutolockEnabled )
{
// Resubscribe before processing new value to prevent missing updates.
Start();
}
TInt screenSaverState;
iScreenSaverActiveProperty.Get( screenSaverState );
// Primary keys are captured from screensaver when screensaver
// is the top most application.
if ( screenSaverState > NULL )
{
__ASSERT_DEBUG( !iCaptured,
Panic( EAknPanicKeyLockObserverAlreadyExists ) );
iScreenSaverActive = ETrue;
CapturePrimaryKeys( ETrue );
}
else
{
// If screensaver is disabled, stop capturing primary key events.
if ( iScreenSaverActive )
{
CapturePrimaryKeys( EFalse );
}
iScreenSaverActive = EFalse;
}
}
// ---------------------------------------------------------------------------
// Set the lock status.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::SetLockStatus( TBool aKeylockEnabled,
TBool aAutolockEnabled )
{
iKeylockEnabled = aKeylockEnabled;
iAutolockEnabled = aAutolockEnabled;
if ( iKeylockEnabled || iAutolockEnabled )
{
// Start observing screensaver activation.
Start();
}
else
{
if ( iScreenSaverActive )
{
CapturePrimaryKeys( EFalse );
}
// Screensaver is only observed when keylock is enabled.
Stop();
}
}
// ---------------------------------------------------------------------------
// Capture or uncapture primary keys.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::CapturePrimaryKeys( TBool aCapture )
{
if ( aCapture )
{
if ( iScreenSaverActive && !iCaptured )
{
if ( iKeylockEnabled && !iAutolockEnabled )
{
iCaptured = ETrue;
// If no unlocking policy has been defined,
// the default primary key is the left soft key.
if ( !iUnlockPolicyApi )
{
// Capture LSK (starts unlock prosess, capturing
// bypasses screensaver)
iLeftSoftKey = iWindowGroup.CaptureKey( EKeyDevice0, 0, 0 );
}
else
{
iPrimaryKeyCaptures.Reset();
TUint32 index( 0 );
TUint32 primaryKey( 0 );
TUint32 secondaryKey( 0 );
while ( iUnlockPolicyApi->GetKeyCombination( index,
primaryKey,
secondaryKey ) == KErrNone )
{
iPrimaryKeyCaptures.Append(
iWindowGroup.CaptureKeyUpAndDowns( primaryKey, 0, 0 ) );
index++;
}
}
}
else
{
if ( iKeylockEnabled && iAutolockEnabled )
{
iCaptured = ETrue;
// If no devicelock query policy has been defined,
// the default primary key is the left soft key.
if ( !iDevicelockPolicyApi )
{
// Capture LSK (starts unlock prosess,
// capturing bypasses screensaver).
iLeftSoftKey = iWindowGroup.CaptureKey( EKeyDevice0, 0, 0 );
}
else
{
iPrimaryKeyCaptures.Reset();
TUint32 index( 0 );
TUint32 primaryKey( 0 );
TUint32 secondaryKey( 0 );
while ( iDevicelockPolicyApi->GetKeyCombination( index, primaryKey, secondaryKey ) == KErrNone )
{
iPrimaryKeyCaptures.Append(
iWindowGroup.CaptureKeyUpAndDowns( primaryKey, 0, 0 ) );
index++;
}
}
}
}
}
}
else
{
if (iCaptured)
{
if (iLeftSoftKey > 0)
{
iWindowGroup.CancelCaptureKey(iLeftSoftKey);
}
iLeftSoftKey = 0;
if (iPrimaryKeyCaptures.Count() > 0)
{
for (TInt x = 0; x < iPrimaryKeyCaptures.Count(); x++)
{
iWindowGroup.CancelCaptureKeyUpAndDowns(iPrimaryKeyCaptures[x]);
}
iPrimaryKeyCaptures.Reset();
}
iCaptured = EFalse;
}
}
}
// ---------------------------------------------------------------------------
// From base class CActive.
// Cancels event listening.
// ---------------------------------------------------------------------------
//
void CAknKeylockScreenSaverObserver::DoCancel()
{
iScreenSaverActiveProperty.Cancel();
}
// ===========================================================================
// class CAknLockedNote.
// ===========================================================================
// ---------------------------------------------------------------------------
// C++ constructor.
// ---------------------------------------------------------------------------
//
CAknLockedNote::CAknLockedNote( TInt& aLocked,
MEikCommandObserver* aCommandObserver )
: CAknSleepingNote( aCommandObserver ),
iLocked( aLocked )
{
AKNTASHOOK_ADD( this, "CAknLockedNote" );
}
// ---------------------------------------------------------------------------
// From base class CAknSleepingNote.
// Handles a dialog button press for the button with ID aCommand.
// ---------------------------------------------------------------------------
//
TBool CAknLockedNote::OkToExitL( TInt aCommand )
{
iLocked = EFalse;
if ( iCommandObserver )
{
iCommandObserver->ProcessCommandL( aCommand );
}
return ETrue;
}
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAknLockedNote::~CAknLockedNote()
{
AKNTASHOOK_REMOVE();
iLocked = EFalse;
}
// ---------------------------------------------------------------------------
// Cancels the note.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::CancelNote()
{
if ( iTimer )
{
iTimer->Cancel();
}
ExitSleepingDialog();
iLocked = EFalse;
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// Handles focus change event.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::FocusChanged( TDrawNow /*aDrawNow*/ )
{
if ( !IsFocused() && iCommandObserver )
{
TRAP_IGNORE( iCommandObserver->ProcessCommandL( KNoteCmdFocusLost ) )
}
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::CEikDialog_Reserved_1()
{
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::CEikDialog_Reserved_2()
{
}
// ---------------------------------------------------------------------------
// From base class CAknNoteDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::CAknNoteDialog_Reserved()
{
}
// ---------------------------------------------------------------------------
// From base class CAknSleepingNote.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknLockedNote::CAknSleepingNote_Reserved()
{
}
// ===========================================================================
// class CAknSleepingNote
// ===========================================================================
// ---------------------------------------------------------------------------
// C++ constructor.
// ---------------------------------------------------------------------------
//
CAknSleepingNote::CAknSleepingNote( MEikCommandObserver* aCommandObserver ) :
iCommandObserver( aCommandObserver )
{
AKNTASHOOK_ADD( this, "CAknSleepingNote" );
}
// ---------------------------------------------------------------------------
// Second-phase constructor.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::ConstructSleepingNoteL( TInt aResourceId )
{
iResourceId = aResourceId;
CAknNoteDialog::ConstructSleepingDialogL( aResourceId );
// Construct now rather than in PreLayoutDynInit.
delete iTimer;
iTimer = NULL;
iTimer = CPeriodic::NewL( 0 );
}
// ---------------------------------------------------------------------------
// Displays the note.
// ---------------------------------------------------------------------------
//
TInt CAknSleepingNote::ShowNote( const TInt aTimeout, const TTone aTone )
{
TRAP_IGNORE(AknGlobalPopupPriorityController::SetPopupPriorityL( *this, KGlobalWindowPriority_KeyLock ));
iTimeoutInMicroseconds = aTimeout;
iTone = aTone;
return RouseSleepingDialog();
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// Handles a dialog button press for the button with ID aCommand.
// ---------------------------------------------------------------------------
//
TBool CAknSleepingNote::OkToExitL( TInt aCommand )
{
if ( iCommandObserver )
{
iCommandObserver->ProcessCommandL( aCommand );
}
return ETrue;
}
// ---------------------------------------------------------------------------
// From base class CAknNoteDialog.
// Updates the note animation on skin change event.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::HandleResourceChange( TInt aType )
{
if ( aType == KAknsMessageSkinChange )
{
TInt animationRes( 0 );
switch ( iResourceId )
{
case R_KEYLOCK_NOTE_KEYLOCKED:
{
animationRes = R_QGN_NOTE_INFO_ANIM;
break;
}
case R_KEYLOCK_NOTE_UNLOCK_CONFIRM:
{
animationRes = R_QGN_NOTE_QUERY_ANIM;
break;
}
case R_KEYLOCK_NOTE_UNLOCK_ASTERISK:
{
animationRes = R_QGN_NOTE_INFO_ANIM;
break;
}
case R_KEYLOCK_NOTE_LOCK_ON:
{
animationRes = R_QGN_NOTE_KEYGUARD_LOCKED_ANIM;
break;
}
case R_KEYLOCK_NOTE_LOCK_OFF:
{
animationRes = R_QGN_NOTE_KEYGUARD_OPEN_ANIM;
break;
}
case R_KEYLOCK_OFFER_LOCK_NOTE:
{
animationRes = R_QGN_NOTE_QUERY_ANIM;
break;
}
default:
{
break;
}
} // end of switch
if ( animationRes )
{
CAknNoteControl* ctrl = NULL;
ctrl = NoteControl();
if ( ctrl )
{
TRAP_IGNORE( ctrl->SetAnimationL( animationRes ) );
}
}
}
CAknNoteDialog::HandleResourceChange( aType );
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::CEikDialog_Reserved_1()
{
}
// ---------------------------------------------------------------------------
// From base class CEikDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::CEikDialog_Reserved_2()
{
}
// ---------------------------------------------------------------------------
// From base class CAknNoteDialog.
// For future use.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::CAknNoteDialog_Reserved()
{
}
// ---------------------------------------------------------------------------
// For future use.
// ---------------------------------------------------------------------------
//
void CAknSleepingNote::CAknSleepingNote_Reserved()
{
}
/**
* CAknEcsNote implements the emergency number display during keylock.
*
* @lib aknoldstylenotif.lib
* @since 3.2
*/
NONSHARABLE_CLASS( CAknEcsNote ): public CAknSleepingNote
{
public:
/**
* Constructor.
*/
CAknEcsNote( MEikCommandObserver* aCommandObserver );
/**
* API to set the emergency number to be displayed
*
* @param aMatchedNumber Text to display (e.g. "112" )
*/
void SetEmergencyNumber( const TDesC& aMatchedNumber );
/**
* Dismisses the sleeping note.
*/
void SleepNote();
public:
/** Is note currently displayed. */
TBool iNoteOnScreen;
};
// ---------------------------------------------------------------------------
// C++ constructor.
// ---------------------------------------------------------------------------
//
CAknEcsNote::CAknEcsNote( MEikCommandObserver* aCommandObserver ) :
CAknSleepingNote( aCommandObserver )
{
}
// ---------------------------------------------------------------------------
// Sets the emergency number to be displayed.
// ---------------------------------------------------------------------------
//
void CAknEcsNote::SetEmergencyNumber( const TDesC& aMatchedNumber )
{
TRect mainPane;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent,
mainPane );
TAknLayoutRect popupNoteWindow;
AknLayoutUtils::TAknCbaLocation cbaLocation(
AknLayoutUtils::CbaLocation() );
TInt variety( 0 );
if ( cbaLocation == AknLayoutUtils::EAknCbaLocationRight )
{
variety = 5;
}
else if ( cbaLocation == AknLayoutUtils::EAknCbaLocationLeft )
{
variety = 8;
}
else
{
variety = 2;
}
popupNoteWindow.LayoutRect(
mainPane,
AknLayoutScalable_Avkon::popup_note_window( variety ) );
TAknLayoutText textRect;
textRect.LayoutText( popupNoteWindow.Rect(),
AknLayoutScalable_Avkon::popup_note_window_t5( 2 ) );
// Size of a temporary buffer that contains new lines, spaces and
// emergency number for a note.
TBuf16<KAknEcsMaxMatchingLength+80> number;
number.Append( '\n' );
number.Append( '\n' );
TInt spaceCharWidthInPixels = textRect.Font()->CharWidthInPixels( ' ' );
if ( spaceCharWidthInPixels < 1 )
{
// Avoid divide by zero situation in case the space character
// would have zero width.
spaceCharWidthInPixels = 1;
}
TInt length = ( textRect.TextRect().Width() -
textRect.Font()->TextWidthInPixels( aMatchedNumber ) ) /
spaceCharWidthInPixels;
const TInt matchedNumberLength = aMatchedNumber.Length();
const TInt numberLength = number.Length();
const TInt numberMaxLength = number.MaxLength();
if ( numberLength + length + matchedNumberLength > numberMaxLength )
{
// To make sure that buffer overflow does not happen.
length = numberMaxLength - numberLength - matchedNumberLength;
}
for ( TInt i = 0; i < length; i++ )
{
number.Append( ' ' );
}
number.Append( aMatchedNumber );
TRAP_IGNORE( SetTextL( number ) );
}
// ---------------------------------------------------------------------------
// Makes the note go to sleep.
// ---------------------------------------------------------------------------
//
void CAknEcsNote::SleepNote()
{
if ( iNoteOnScreen )
{
// Causes flicker to other notes if called when note is not on screen.
ExitSleepingDialog();
}
iNoteOnScreen = EFalse;
}
// ===========================================================================
// class CAknKeyLockControl
// ===========================================================================
// ---------------------------------------------------------------------------
// Default constructor.
// ---------------------------------------------------------------------------
//
CAknKeyLockControl::CAknKeyLockControl() :
iConsumeNextEventKey( EFalse )
{
AKNTASHOOK_ADD( this, "CAknKeyLockControl" );
}
// ---------------------------------------------------------------------------
// C++ constructor.
// ---------------------------------------------------------------------------
//
CAknKeyLockControl::CAknKeyLockControl( CAknKeyLockNotifierSubject* aNotif ) :
iNotif( aNotif )
{
AKNTASHOOK_ADD( this, "CAknKeyLockControl" );
}
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAknKeyLockControl::~CAknKeyLockControl()
{
AKNTASHOOK_REMOVE();
// We implicitely trust that Eikon env exists
// (though in practice it does not make the
// difference as this destructor is really never called...)
RWindowGroup& groupWin = iEikonEnv->RootWin();
groupWin.CancelCaptureKey( iEditKeyL );
groupWin.CancelCaptureKey( iEditKeyR );
AknGlobalPopupPriorityController::RemovePopupPriority( *this );
FeatureManager::UnInitializeLib();
iEikonEnv->EikAppUi()->RemoveFromStack( this );
iStatusProperty.Close();
delete iConfirmationNote;
delete iConfirmationNoteAsterisk;
delete iLockedNote;
delete iKeypadUnlockedNote;
delete iKeypadLockedNote;
delete iEcsDetector;
delete iKeyLockCba;
delete iOfferLockNote;
delete iEcsNote; // Ecs change
delete iKeylockApi;
delete iKeylockScreenSaverObserver;
}
// ---------------------------------------------------------------------------
// Second phase construction.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::ConstructL()
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::ConstructL ")); )
FeatureManager::InitializeLibL();
iFeatureKeypadNoSlider =
FeatureManager::FeatureSupported( KFeatureIdKeypadNoSlider );
iFeatureNoPowerkey =
FeatureManager::FeatureSupported( KFeatureIdNoPowerkey );
// Keyguard switch support.
CRepository* repository = CRepository::NewLC( KCRUidLockConf );
TInt hardwareSupport( 0 );
repository->Get( KKeyguardHardwareConf, hardwareSupport );
CleanupStack::PopAndDestroy( repository );
iHardwareSupport = TLockHardware( hardwareSupport );
CreateWindowL();
Window().SetSize( TSize( 0, 0 ) );
ActivateL();
AknGlobalPopupPriorityController::SetPopupPriorityL(
*this, KGlobalWindowPriority_KeyLock );
// To allow HW keys for key filter even if keypad is locked.
iEikonEnv->EikAppUi()->AddToStackL( this,
ECoeStackPriorityEnvironmentFilter - 1,
ECoeStackFlagRefusesFocus );
iEcsNote = new (ELeave) CAknEcsNote( this );
iEcsNote->ConstructSleepingNoteL( R_AVKON_EMERGENCY_CALL_NOTE );
iEcsNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
iOfferLockNote = new (ELeave) CAknLockedNote( iOfferLockEnabled, this );
iOfferLockNote->ConstructSleepingNoteL( R_KEYLOCK_OFFER_LOCK_NOTE );
iOfferLockNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
TBool touchEnabled( AknLayoutUtils::PenEnabled() );
TBool hasSlider = HasSliderKey();
iKeyLockCba = CEikButtonGroupContainer::NewL(
CEikButtonGroupContainer::ECba,
CEikButtonGroupContainer::EHorizontal,
this,
(touchEnabled&&hasSlider) ? R_AVKON_SOFTKEYS_EMPTY :
R_KEYLOCK_SOFTKEYS_UNLOCK_EMPTY );
iKeyLockCba->ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition(
ECoeWinPriorityNeverAtFront );
TRect screenRect;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
iKeyLockCba->SetBoundingRect( screenRect );
iKeyLockCba->MakeVisible( EFalse );
// Construct the "keypad locked" note.
iKeypadLockedNote = new (ELeave) CAknSleepingNote();
iKeypadLockedNote->ConstructSleepingNoteL(
touchEnabled ? R_KEYLOCK_NOTE_DISPLAY_LOCK_ON_TOUCH :
R_KEYLOCK_NOTE_LOCK_ON );
iKeypadLockedNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
iKeypadLockedNote->PublishDialogL( EAknKeysLockedNote );
// Construct the "keypad unlocked" note.
iKeypadUnlockedNote = new (ELeave) CAknSleepingNote();
iKeypadUnlockedNote->ConstructSleepingNoteL(
touchEnabled ? R_KEYLOCK_NOTE_DISPLAY_LOCK_OFF_TOUCH :
R_KEYLOCK_NOTE_LOCK_OFF );
iKeypadUnlockedNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
iKeypadUnlockedNote->PublishDialogL( EAknKeysReleasedNote );
// Construct the locked note.
iLockedNote = new (ELeave) CAknLockedNote( iLockedNoteDisplayed );
if ( touchEnabled )
{
iLockedNote->ConstructSleepingNoteL( R_KEYLOCK_NOTE_DISPLAY_LOCKED_TOUCH );
}
else
{
switch ( iHardwareSupport )
{
case EKeyguardOnePositionSwitch:
case EKeyguardTwoPositionSwitch:
{
iLockedNote->ConstructSleepingNoteL( R_KEYLOCK_NOTE_KEYLOCKED_SWITCH );
break;
}
case EKeyguardDefaultHardware:
default:
{
iLockedNote->ConstructSleepingNoteL( R_KEYLOCK_NOTE_KEYLOCKED );
break;
}
}
}
iLockedNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
if ( !(touchEnabled&&hasSlider) )
{
// These are created only if touch is not enabled, since
// currently in touch devices the keylock state is controlled
// with switch.
// Construct the confirmation note for unlocking keypad.
iConfirmationNote = new (ELeave) CAknLockedNote( iUnlockConfirmation );
iConfirmationNote->ConstructSleepingNoteL( R_KEYLOCK_NOTE_UNLOCK_CONFIRM );
iConfirmationNote->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
if ( iFeatureKeypadNoSlider )
{
// Show note "Now press *".
// Note is shown when user has pressed "Unlock" when
// keypad is in locked state
iConfirmationNoteAsterisk =
new (ELeave) CAknLockedNote( iUnlockConfirmation );
TInt fileExist = KErrNone;
CFindFileByType* pFindFile = new (ELeave) CFindFileByType(iEikonEnv->FsSession());
fileExist = pFindFile->FindFirst(UNLOCKKEY_MIF_FILE_UNICODE, _L(""), KNullUid);
delete pFindFile;
if (KErrNone != fileExist)
{
iConfirmationNoteAsterisk->ConstructSleepingNoteL(
R_KEYLOCK_NOTE_UNLOCK_ASTERISK);
}
else
{
iConfirmationNoteAsterisk->ConstructSleepingNoteL(
R_KEYLOCK_NOTE_UNLOCK_ASTERISK_ANIM_UNTOUCH);
}
iConfirmationNoteAsterisk->ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition( 0, 2 );
}
}
// Emergency call support.
iEcsDetector = CAknEcsDetector::NewL();
iEcsDetector->SetObserver( this );
// As edit keys (shifts) shouldn't be passed to application as
// EEventKey, capture those here.
RWindowGroup& groupWin = iEikonEnv->RootWin();
iEditKeyL = groupWin.CaptureKey( EKeyLeftShift, 0, 0 );
iEditKeyR = groupWin.CaptureKey( EKeyRightShift, 0, 0 );
// Create keylock policy component if an unlocking policy has been defined.
iKeylockApi = CKeyLockPolicyApi::NewL( EPolicyDeactivateKeyguard );
if ( !iKeylockApi->HasConfiguration() )
{
// Keylock API not initialized.
delete iKeylockApi;
iKeylockApi = NULL;
}
iKeylockScreenSaverObserver =
CAknKeylockScreenSaverObserver::NewL( groupWin );
// Define P&S key that is used to publish the keyguard status.
RProperty::Define( KPSUidAvkonDomain,
KAknKeyguardStatus,
RProperty::EInt,
TSecurityPolicy( TSecurityPolicy::EAlwaysPass ),
KWritePolicy );
iStatusProperty.Attach( KPSUidAvkonDomain, KAknKeyguardStatus );
iStatusProperty.Set( EKeyguardNotActive );
}
// ---------------------------------------------------------------------------
// Enable key lock.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::EnableKeylock( TBool aShowNote, TBool aNotifySysApp )
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::EnableKeylock %d"), aShowNote); )
// Policy can be used to disable support for keyguard.
if ( !iAutolockEnabled && !CKeyLockPolicyApi::KeyguardAllowed() )
{
// Keylock Disabled
return;
}
// Keylock Enabled
iKeylockScreenSaverObserver->SetLockStatus( ETrue, iAutolockEnabled );
if ( iOfferLockEnabled )
{
iOfferLockNote->CancelNote();
}
// Update keyguard status to P&S system.
iStatusProperty.Set( iAutolockEnabled ? EKeyguardAutolockEmulation :
EKeyguardLocked );
iKeyLockEnabled = ETrue;
if ( !iAutolockEnabled && aNotifySysApp )
{
SendMessageToSysAp( EEikKeyLockEnabled );
}
TBool hasSliderKey = HasSliderKey();
if ( !AknLayoutUtils::PenEnabled() || !hasSliderKey)
{
iKeyLockCba->MakeVisible( ETrue );
}
else
{
iKeyLockCba->MakeVisible( EFalse );
}
TBool areWeInIdleState = CEikStatusPaneBase::Current()->PaneCapabilities(
TUid::Uid( EEikStatusPaneUidClock ) ).IsInCurrentLayout();
if ( areWeInIdleState )
{ // idle state
static_cast<CEikCba*>(
iKeyLockCba->ButtonGroup() )->SetSkinBackgroundId(
KAknsIIDQsnBgAreaControlIdle );
}
else
{
static_cast<CEikCba*>(
iKeyLockCba->ButtonGroup() )->SetSkinBackgroundId(
KAknsIIDQsnBgAreaControl );
}
AknGlobalPopupPriorityController::ShowPopup( *this, ETrue );
if ( aShowNote )
{
DisplayLockedNote();
}
if ( !AknLayoutUtils::PenEnabled() || !hasSliderKey)
{
ShowKeylockCba();
}
else
{
// Set the window screen sized and make it transparent.
TRect screenRect;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
Window().SetSize( screenRect.Size() );
Window().SetRequiredDisplayMode( EColor16MA );
TInt err = Window().SetTransparencyAlphaChannel();
if ( err == KErrNone )
{
Window().SetBackgroundColor( ~0 );
}
}
// in case Telephone-app is topmost, then the user is confused because he sees but can't use it.
// therefore it's required to hide it, by sending to background. ETMA-7M8A2Y 20090105
if ( AknLayoutUtils::PenEnabled() )
{
TApaTaskList apaTaskList(CCoeEnv::Static()->WsSession());
#define KPhoneAppUid TUid::Uid(0x100058B3)
TApaTask apaTask = apaTaskList.FindApp(KPhoneAppUid);
if (apaTask.Exists())
{
#if defined(_DEBUG)
RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::EnableKeylock() Bring phone to background"));
#endif
// Bring phone to background
apaTask.SendToBackground();
}
}
// Start capturing system keys.
CaptureSystemKeys();
// Capture all pointer events.
CapturePointerEvents();
iEcsDetector->ConnectToEventSource();
if ( iNotif )
{
iNotif->NotifyStatusChange( EKeyLockEnabled );
}
if ( !iSoundsMuted )
{
CAknAppUiBase* appUi = iAvkonAppUiBase;
TRAPD( err, appUi->KeySounds()->PushContextL( R_AVKON_SILENT_SKEY_LIST ) );
if ( !err )
{
appUi->KeySounds()->BringToForeground();
appUi->KeySounds()->LockContext();
iSoundsMuted = ETrue;
}
}
// Basically this cannot fail so we ignore return code.
static_cast<CAknNotifierAppServerAppUi*>(
iEikonEnv->EikAppUi() )->SuppressAppSwitching( ETrue );
// Method HandleResourceChangeL with parameter KAknInternalFSWClose cannot
// leave, but we trap it in just in case.
TRAP_IGNORE( static_cast<CAknCapAppServerAppUi*>( iEikonEnv->EikAppUi() )->HandleResourceChangeL(
KAknInternalFSWClose ); );
}
// ---------------------------------------------------------------------------
// Disable key lock.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DisableKeylock(TBool aNotifySysApp)
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::DisableKeylock")); )
// Keep locking status in sync.
iKeylockScreenSaverObserver->SetLockStatus( EFalse, iAutolockEnabled );
if ( iSoundsMuted )
{
CAknAppUiBase* appUi= iAvkonAppUiBase;
appUi->KeySounds()->ReleaseContext();
appUi->KeySounds()->PopContext();
iSoundsMuted = EFalse;
}
iEcsDetector->CloseEventSource();
// Stop capturing system keys.
UnCaptureSystemKeys();
// Stop capturing pointer events.
UnCapturePointerEvents();
AknGlobalPopupPriorityController::ShowPopup( *this, EFalse );
// Make the window "disappear".
Window().SetSize( TSize( 0, 0 ) );
iKeyLockCba->ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition(
ECoeWinPriorityNeverAtFront );
iKeyLockCba->MakeVisible( EFalse );
// Update keyguard status to P&S system.
iStatusProperty.Set( EKeyguardNotActive );
iKeyLockEnabled = EFalse;
if ( !iAutolockEnabled ) // only when Autolock was user-activated
{
// in case Telephone-app was topmost and sent to background, then the user is confused because he expects to see it again.
// therefore it's required to show it, by sending to foreground.
if ( AknLayoutUtils::PenEnabled() )
{
TInt callState;
RProperty::Get( KPSUidCtsyCallInformation, KCTsyCallState, callState );
#if defined(_DEBUG)
RDebug::Printf( "%s %s (%u) callState=%x", __FILE__, __PRETTY_FUNCTION__, __LINE__, callState );
RDebug::Printf( "%s %s (%u) EPSCTsyCallStateNone=%x", __FILE__, __PRETTY_FUNCTION__, __LINE__, EPSCTsyCallStateNone );
#endif
if (callState != EPSCTsyCallStateNone )
{
TApaTaskList apaTaskList(CCoeEnv::Static()->WsSession());
#define KPhoneAppUid TUid::Uid(0x100058B3)
TApaTask apaTask = apaTaskList.FindApp(KPhoneAppUid);
if (apaTask.Exists())
{
RDebug::Printf( "%s %s (%u) foreground=%x", __FILE__, __PRETTY_FUNCTION__, __LINE__, 1 );
#if defined(_DEBUG)
RDebug::Print(_L("(AUTOLOCK)CAknKeyLockControl::EnableKeylock() Send phone to foreground"));
#endif
// Bring phone to foreground
apaTask.BringToForeground();
}
}
} // PenEnabled()
if (aNotifySysApp)
{
SendMessageToSysAp( EEikKeyLockDisabled );
}
}
if ( iNotif )
{
iNotif->NotifyStatusChange( EKeyLockDisabled );
}
// Basically this cannot fail so we ignore return code.
static_cast<CAknNotifierAppServerAppUi*>(
iEikonEnv->EikAppUi() )->SuppressAppSwitching( EFalse );
iAutolockEnabled = EFalse;
}
// ---------------------------------------------------------------------------
// Sends a message to the SysAp window group.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::SendMessageToSysAp( TInt aMessage )
{
RWsSession& ws = iEikonEnv->WsSession();
TInt wgId = 0;
CApaWindowGroupName::FindByAppUid( KSysApUid, ws, wgId );
if ( wgId )
{
TWsEvent event;
event.SetType( aMessage );
event.SetTimeNow();
ws.SendEventToWindowGroup( wgId, event );
}
}
// ---------------------------------------------------------------------------
// Displays the "offer keylock" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::OfferKeylock()
{
iOfferLockNote->ShowNote( (CAknNoteDialog::TTimeout)KAknOfferKeyLockTimeout,
CAknNoteDialog::ENoTone );
iOfferLockEnabled = ETrue;
}
// ---------------------------------------------------------------------------
// Displays the "locked" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DisplayLockedNote()
{
if ( !iAutolockEnabled )
{
}
}
// ---------------------------------------------------------------------------
// Displays the "keys active" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DisplayKeyActiveNote()
{
if ( !iAutolockEnabled )
{
}
}
// ---------------------------------------------------------------------------
// Unlocks the keypad and displays the "keys active" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DoUnlock()
{
DisableKeylock();
DisplayKeyActiveNote();
}
// ---------------------------------------------------------------------------
// From base class CCoeControl.
// Handles resource change events.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::HandleResourceChange( TInt aType )
{
if ( aType == KEikDynamicLayoutVariantSwitch )
{
TRect screenRect;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
if ( !AknLayoutUtils::PenEnabled() )
{
iKeyLockCba->SetBoundingRect( screenRect );
}
else if ( iKeyLockEnabled )
{
// Only resize the window if keylock is active, as
// the window size must be zero when keylock is not active.
// The window is resized to correct size when keylock is activated.
Window().SetSize( screenRect.Size() );
Window().SetRequiredDisplayMode( EColor16MA );
TInt err = Window().SetTransparencyAlphaChannel();
if ( err == KErrNone )
{
Window().SetBackgroundColor( ~0 );
}
}
}
}
// ---------------------------------------------------------------------------
// From base class MEikCommandObserver.
// Process commands.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::ProcessCommandL( TInt aCommandId )
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::ProcessCommandL %d"), aCommandId); )
switch ( aCommandId )
{
case EAknSoftkeyUnlock:
{
if ( iAutolockEnabled && !iKeylockApi )
{
TApaTaskList tasklist( iCoeEnv->WsSession() );
TApaTask autolocktask = tasklist.FindApp( KAutolockUid );
if ( autolocktask.Exists() )
{
// if Autolock application is ready
DisableKeylock();
iNotif->NotifyStatusChange( EHideSoftNotifications );
TKeyEvent keyEvent;
keyEvent.iCode = EKeyBell;
autolocktask.SendKey( keyEvent );
}
}
else
{
LeftSoftKeyPressed();
}
break;
}
case EAknSoftkeyLock:
{
// Lock keys
DoExitOfferKeylock();
EnableKeylock();
break;
}
case EAknSoftkeyExit:
{
// Cancel offer keylock CBA
DoExitOfferKeylock();
break;
}
case EAknSoftkeyEmpty:
{
if ( iKeyLockEnabled )
{
ShowLockedNote();
}
break;
}
case KNoteCmdFocusLost:
{
// Locked note has become unfocused - get rid of it.
if ( iOfferLockEnabled )
{
DoExitOfferKeylock();
}
break;
}
default:
{
break;
}
}
}
// ---------------------------------------------------------------------------
// From base class CCoeControl.
// Gets the amount of component controls.
// ---------------------------------------------------------------------------
//
TInt CAknKeyLockControl::CountComponentControls() const
{
if ( iKeyLockEnabled )
{
return 1;
}
else
{
return 0;
}
}
// ---------------------------------------------------------------------------
// From base class CCoeControl.
// Returns the pointer to a component control.
// ---------------------------------------------------------------------------
//
CCoeControl* CAknKeyLockControl::ComponentControl( TInt /*aIndex*/ ) const
{
if ( iKeyLockEnabled )
{
return iKeyLockCba;
}
else
{
return NULL;
}
}
// ---------------------------------------------------------------------------
// Handles LSK keypress.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::LeftSoftKeyPressed()
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::LeftSoftKeyPressed")); )
// Check that the confirmation note exists, as it's not created on
// startup if touch layout is in use. In emulator this might cause
// a problem, as layout can be changed to a non-touch one, and
// the confirmation notes do not exist.
if ( iConfirmationNote )
{
if ( iFeatureKeypadNoSlider )
{
// Show note "Now press *".
// Note is shown when user has pressed "Unlock" when keypad
// is in locked state.
iConfirmationNoteAsterisk->ShowNote( CAknNoteDialog::EShortTimeout,
CAknNoteDialog::EConfirmationTone );
}
else
{
iConfirmationNote->ShowNote( CAknNoteDialog::EShortTimeout,
CAknNoteDialog::EConfirmationTone );
}
SendMessageToSysAp( EEikKeyLockLightsOnRequest );
iUnlockConfirmation = ETrue;
}
}
// ---------------------------------------------------------------------------
// From base class CCoeControl.
// Handle key events.
// ---------------------------------------------------------------------------
//
TKeyResponse CAknKeyLockControl::OfferKeyEventL( const TKeyEvent& aKeyEvent,
TEventCode aType )
{
if ( AknLayoutUtils::PenEnabled() )
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::OfferKeyEventL: PenEnabled"));)
if ( iAutolockEnabled )
{ // The case when touch device is locked and so must be unlocked by hold switch.
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::OfferKeyEventL: Autolock Enabled"));)
if ( aType == EEventKey && aKeyEvent.iCode == EKeyDeviceF )
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::OfferKeyEventL: SysAp message"));)
SendMessageToSysAp( EEikKeyLockLightsOnRequest );
if ( iAutolockEnabled && !iKeylockApi )
{
TApaTaskList tasklist( iCoeEnv->WsSession() );
TApaTask autolocktask = tasklist.FindApp( KAutolockUid );
if ( autolocktask.Exists() )
{
// If Autolock application is ready
DisableKeylock();
iNotif->NotifyStatusChange( EHideSoftNotifications );
TKeyEvent keyEvent;
keyEvent.iCode = EKeyBell;
autolocktask.SendKey( keyEvent );
}
}
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::OfferKeyEventL: return EKeyWasConsumed"));)
return EKeyWasConsumed;
}
}
}
if ( !iOfferLockEnabled && !iKeyLockEnabled )
{
if ( aType == EEventKey &&
( aKeyEvent.iCode == EKeyLeftShift ||
aKeyEvent.iCode == EKeyRightShift ) )
{
// Eat these events as they just cause problems elsewhere.
return EKeyWasConsumed;
}
if ( iKeylockApi && iConsumeNextEventKey )
{
if ( aType == EEventKeyUp )
{
iConsumeNextEventKey = EFalse;
}
return EKeyWasConsumed;
}
return EKeyWasNotConsumed;
}
if ( ( aType == EEventKey && aKeyEvent.iRepeats == 0 ) ||
( aType == EEventKeyDown && aKeyEvent.iScanCode == EStdKeyDevice2 ) ) // Power key
{
// If power key pressed, tell SysAp about it.
if ( ( aKeyEvent.iScanCode == EStdKeyDevice2 && aType == EEventKeyDown ) ||
( iFeatureNoPowerkey && aKeyEvent.iCode == EKeyNo ) )
{
SendMessageToSysAp( EEikKeyLockPowerKeyPressed );
if ( iFeatureNoPowerkey )
{
SendMessageToSysAp( EEikKeyLockLightsOnRequest );
}
}
}
// Product uses a Keylock Policy API if there exists a defined
// unlock configuration.
if ( iKeylockApi && iKeyLockEnabled )
{
// For keyguard policy
if ( !iAutolockEnabled )
{
// Send key events to KeylockPolicy first
if ( iKeylockApi->HandleKeyEventL( aKeyEvent, aType ) )
{
// Key combinations has been pressed -> unlocking.
DoUnlock();
iConsumeNextEventKey = ETrue;
}
else
{
// Key combination is not complete.
if ( iKeylockApi->PrimaryKeyPressed() )
{
if ( iKeylockApi->GetLastPrimaryKey() == aKeyEvent.iScanCode &&
aType == EEventKeyDown )
{
// Only primary key has been pressed - show
// how to unlock "Now press *"
LeftSoftKeyPressed();
}
}
else
{
// Not the primary key has been pressed.
if ( aType == EEventKeyDown &&
!( iEcsNote->iNoteOnScreen && aKeyEvent.iCode == EKeyYes ) )
{
ShowLockedNote();
}
}
}
}
// for autolock policy
else
{
if ( aType == EEventKeyDown )
{
TApaTaskList tasklist( iCoeEnv->WsSession() );
TApaTask autolocktask = tasklist.FindApp( KAutolockUid );
if ( autolocktask.Exists() )
{
autolocktask.SendKey( aKeyEvent );
}
}
}
return EKeyWasConsumed;
}
if ( ( aType == EEventKey && aKeyEvent.iRepeats == 0 ) ||
( aType == EEventKeyDown && aKeyEvent.iScanCode == EStdKeyDevice2 ) ) // Power key
{
if ( iOfferLockEnabled )
{
switch ( aKeyEvent.iCode )
{
case EKeyOK: // fallthrough to return EKeyWasConsumed
{
DoExitOfferKeylock();
EnableKeylock();
}
case EKeyLeftArrow:
case EKeyRightArrow:
case EKeyUpArrow:
case EKeyDownArrow:
case EKeyApplication:
{
return EKeyWasConsumed;
}
default:
{
// Normal response - send it to the CBA via the
// control stack.
return EKeyWasNotConsumed;
}
}
}
else if ( iKeyLockEnabled )
{
if ( iLockedNoteDisplayed )
{
// See if 'Unlock' has been pressed.
if ( aKeyEvent.iCode == EKeyCBA1 )
{
LeftSoftKeyPressed();
iLockedNote->CancelNote();
}
// Locked note is on-screen - discard key.
return EKeyWasConsumed;
}
else if ( iUnlockConfirmation )
{
// Confirmation note is on-screen - check for OK.
// EStdKeyDevice1 is also needed since some applications generate
// EKeyCBA2 key events and accidentally unlock the phone
if ( ( ( aKeyEvent.iCode == KAknAsterisk ||
aKeyEvent.iCode == KAknChineseAsterisk ) &&
iFeatureKeypadNoSlider ) ||
( aKeyEvent.iCode == EKeyCBA2 &&
aKeyEvent.iScanCode == EStdKeyDevice1 &&
!iFeatureKeypadNoSlider ) )
{
DoUnlock();
if ( iFeatureKeypadNoSlider )
{
// Show note "Now press *".
// Note is shown when user has pressed "Unlock"
// when keypad is in locked state
iConfirmationNoteAsterisk->CancelNote();
}
else
{
iConfirmationNote->CancelNote();
}
}
else
{
if ( aKeyEvent.iCode != EKeyCBA1 &&
aKeyEvent.iCode != EKeyLeftShift &&
aKeyEvent.iCode != EKeyRightShift )
{
ShowLockedNote();
}
}
}
else
{
TKeyResponse cbaResponse = EKeyWasNotConsumed;
// EKeyOK will be incorrectly translated to left soft key by the CBA.
if ( aKeyEvent.iCode != EKeyOK )
{
// Normal response - send it to the CBA.
cbaResponse =
iKeyLockCba->ButtonGroup()->AsControl()->OfferKeyEventL(
aKeyEvent, aType );
}
if ( cbaResponse == EKeyWasNotConsumed )
{
if ( !( iEcsNote->iNoteOnScreen &&
aKeyEvent.iCode == EKeyYes ) )
{
ShowLockedNote();
}
}
}
}
}
// Needed for the pencil key/shift keys to show "keys locked" note.
else if ( iKeyLockEnabled )
{
if ( aType == EEventKeyDown &&
aKeyEvent.iRepeats == 0 &&
( aKeyEvent.iScanCode == EStdKeyLeftShift ||
aKeyEvent.iScanCode == EStdKeyRightShift ) )
{
ShowLockedNote();
}
}
return EKeyWasConsumed;
}
// ---------------------------------------------------------------------------
// Shows the "locked" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::ShowLockedNote()
{
if ( !iLockedNoteDisplayed )
{
DoShowLockedNote();
}
}
// ---------------------------------------------------------------------------
// Shows the "locked" note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DoShowLockedNote()
{
if ( !iAutolockEnabled )
{
}
}
// ---------------------------------------------------------------------------
// Brings the keylock notifier's CBA visible.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::ShowKeylockCba()
{
RDrawableWindow* cbaWindow =
iKeyLockCba->ButtonGroup()->AsControl()->DrawableWindow();
cbaWindow->SetFaded( EFalse, RWindowTreeNode::EFadeWindowOnly );
cbaWindow->SetOrdinalPosition( 0, 1 );
cbaWindow->SetNonFading( ETrue );
}
// ---------------------------------------------------------------------------
// Sets the necessary HW keys captured.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::CaptureSystemKeys()
{
if ( !iKeysCaptured )
{
RWindowGroup& groupWin = iCoeEnv->RootWin();
// Capture app key (disable application switching).
iAppKey = groupWin.CaptureKeyUpAndDowns( EStdKeyApplication0, 0, 0 );
iAppKey2 = groupWin.CaptureKey( EKeyApplication0, 0, 0 );
// Capture power key (for lights).
iPowerKey = groupWin.CaptureKeyUpAndDowns( EStdKeyDevice2, 0, 0 );
iPowerKey2 = groupWin.CaptureKey( EKeyDevice2, 0, 0 );
// Capture voice key.
iVoiceKey = groupWin.CaptureKeyUpAndDowns( EStdKeyDevice6, 0, 0 );
iVoiceKey2 = groupWin.CaptureKey( EKeyDevice6, 0, 0 );
// Capture end key (lights for combined power/end key).
iEndKey = groupWin.CaptureKey( EKeyNo, 0, 0 );
// Capture PoC key.
iPoCKey = groupWin.CaptureKeyUpAndDowns( EStdKeyApplication1, 0, 0 );
iPoCKey2 = groupWin.CaptureKey( EKeyApplication1, 0, 0 );
iHoldSwitch = 0;
if ( AknLayoutUtils::PenEnabled() )
{
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::CaptureSystemKeys PenEnabled"));)
if ( iAutolockEnabled )
{ //Capture Hold Switch
TRACES( RDebug::Print(_L("(KeyGuard)CAknKeyLockControl::CaptureSystemKeys iAutolockEnabled"));)
iHoldSwitch = groupWin.CaptureKey( EKeyDeviceF, 0, 0 );
}
}
iKeysCaptured = ETrue;
}
}
// ---------------------------------------------------------------------------
// Releases captured HW keys.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::UnCaptureSystemKeys()
{
if ( iKeysCaptured )
{
RWindowGroup& groupWin = iCoeEnv->RootWin();
groupWin.CancelCaptureKeyUpAndDowns( iAppKey );
groupWin.CancelCaptureKeyUpAndDowns( iPowerKey );
groupWin.CancelCaptureKeyUpAndDowns( iVoiceKey );
groupWin.CancelCaptureKey( iAppKey2 );
groupWin.CancelCaptureKey( iPowerKey2 );
groupWin.CancelCaptureKey( iVoiceKey2 );
groupWin.CancelCaptureKey( iEndKey );
groupWin.CancelCaptureKeyUpAndDowns( iPoCKey );
groupWin.CancelCaptureKey( iPoCKey2 );
if ( iHoldSwitch > 0 )
{
groupWin.CancelCaptureKey( iHoldSwitch );
}
iKeysCaptured = EFalse;
}
}
// ---------------------------------------------------------------------------
// From base class MAknEcsObserver.
// Handles the ECS events.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::HandleEcsEvent( CAknEcsDetector* aEcsDetector,
CAknEcsDetector::TState aState )
{
switch ( aState )
{
case CAknEcsDetector::ECompleteMatchThenSendKey:
{
// Do nothing since note will be removed on ECallAttempted event.
break;
}
case CAknEcsDetector::ECompleteMatch:
case CAknEcsDetector::EServiceNumMatch:
{
iEcsNote->SetEmergencyNumber( aEcsDetector->CurrentMatch() );
iEcsNote->ShowNote( CAknNoteDialog::ENoTimeout,
CAknNoteDialog::ENoTone );
// Tell SysAp to switch lights on.
SendMessageToSysAp( EEikEcsQueryLights );
iEcsNote->iNoteOnScreen = ETrue;
break;
}
case CAknEcsDetector::EPartialMatch:
{
iEcsNote->SleepNote();
break;
}
case CAknEcsDetector::ECallAttempted:
{
iEcsNote->SleepNote();
break;
}
case CAknEcsDetector::EEmpty:
{
iEcsNote->SleepNote();
break;
}
case CAknEcsDetector::ENoMatch:
{
iEcsNote->SleepNote();
break;
}
default:
{
break;
}
}
}
// ---------------------------------------------------------------------------
// Cancels the offer keylock note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::DoExitOfferKeylock()
{
iOfferLockNote->CancelNote();
}
// ---------------------------------------------------------------------------
// Cancels the offer keylock note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::OfferTimerExpired()
{
DoExitOfferKeylock();
}
// ---------------------------------------------------------------------------
// Sets the autolock state.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::AutolockEnabled( TBool aAutoLockOn )
{
iAutolockEnabled = aAutoLockOn;
}
// ---------------------------------------------------------------------------
// For CDMA implementation.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::CallNumberL( TDesC& /*aNumber*/ )
{
}
// ---------------------------------------------------------------------------
// For CDMA implementation.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::ShowLockPhoneQueryL()
{
}
// ---------------------------------------------------------------------------
// For capturing pointer events when key lock is enabled.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::CapturePointerEvents()
{
if ( AknLayoutUtils::PenEnabled() )
{
Window().SetPointerCapture( RWindowBase::TCaptureDragDrop );
Window().ClaimPointerGrab( ETrue );
}
}
// ---------------------------------------------------------------------------
// For releasing pointer events when key lock is disabled.
// ---------------------------------------------------------------------------
//
void CAknKeyLockControl::UnCapturePointerEvents()
{
if ( AknLayoutUtils::PenEnabled() )
{
Window().SetPointerCapture( RWindowBase::TCaptureDisabled );
Window().ClaimPointerGrab( EFalse );
}
}
TBool CAknKeyLockControl::HasSliderKey()
{
TBool hasSlider(iHardwareSupport != EKeyguardDefaultHardware);
if( FeatureManager::FeatureSupported( KFeatureIdFfPowerKeyAsKeyguard ) )
{
hasSlider = ETrue; // the only purpose is to display empty sotkeys
}
return hasSlider;
}
// ===========================================================================
// class CAknKeyLockNotifierSubject
// ===========================================================================
// ---------------------------------------------------------------------------
// Two-phased constructor.
// ---------------------------------------------------------------------------
//
CAknKeyLockNotifierSubject* CAknKeyLockNotifierSubject::NewL()
{
CAknKeyLockNotifierSubject* self = new (ELeave) CAknKeyLockNotifierSubject();
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------------------------
// Second-phase constructor.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::ConstructL()
{
CCoeEnv* environment = CCoeEnv::Static();
TFileName resourceFile;
resourceFile.Append( KRESOURCEFILE );
BaflUtils::NearestLanguageFile( environment->FsSession(), resourceFile );
iResourceFileOffset = environment->AddResourceFileL( resourceFile );
iObserverList = new (ELeave) CArrayPtrFlat<MAknKeyLockObserver>(
KAknObserverListGranularity );
iKeyLockControl = new (ELeave) CAknKeyLockControl( this );
iKeyLockControl->ConstructL();
}
// ---------------------------------------------------------------------------
// Default C++ constructor.
// ---------------------------------------------------------------------------
//
CAknKeyLockNotifierSubject::CAknKeyLockNotifierSubject() :
iAllowNotifications( ETrue )
{
}
// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CAknKeyLockNotifierSubject::~CAknKeyLockNotifierSubject()
{
if ( iResourceFileOffset )
{
CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset );
}
delete iKeyLockControl;
delete iObserverList;
iKeyLockControl = NULL;
iObserverList = NULL;
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Frees all the resources owned by the keylock notifier.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::Release()
{
delete this;
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Initialises the keylock notifier.
// ---------------------------------------------------------------------------
//
CAknKeyLockNotifierSubject::TNotifierInfo CAknKeyLockNotifierSubject::RegisterL()
{
iInfo.iUid = KAknKeyLockNotifierUid;
iInfo.iChannel = KAknKeyLockNotifierUid;
iInfo.iPriority = ENotifierPriorityHigh;
return iInfo;
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Gets the notifier parameters.
// ---------------------------------------------------------------------------
//
CAknKeyLockNotifierSubject::TNotifierInfo CAknKeyLockNotifierSubject::Info() const
{
return iInfo;
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Starts the keylock notifier synchronously.
// ---------------------------------------------------------------------------
//
TPtrC8 CAknKeyLockNotifierSubject::StartL( const TDesC8& aBuffer )
{
SAknNotifierPackage<SAknKeyLockNotifierParams>* params =
( SAknNotifierPackage<SAknKeyLockNotifierParams>*)aBuffer.Ptr();
if ( aBuffer.Length() < 0 ||
(TUint)aBuffer.Length() < sizeof(SAknNotifierPackage<SAknKeyLockNotifierParams>) ||
params->iSignature != KAKNNOTIFIERSIGNATURE )
{
User::Leave( KErrArgument );
}
switch ( params->iParamData.iReason )
{
case ELockEnabled:
case ELockDisabled:
case EAllowNotifications:
case EStopNotifications:
case EOfferKeylock:
case ECancelAllNotifications:
case EEnableAutoLockEmulation:
case EDisableWithoutNote:
case EEnableWithoutNote:
{
break;
}
case EInquire:
{
iRetPckg().iEnabled = IsKeyLockEnabled();
break;
}
default:
{
break;
}
}
return iRetPckg;
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Starts the keylock notifier asynchronously.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::StartL( const TDesC8& aBuffer,
TInt /*aReplySlot*/,
const RMessagePtr2& aMessage )
{
SAknNotifierPackage<SAknKeyLockNotifierParams>* params =
( SAknNotifierPackage<SAknKeyLockNotifierParams>*)aBuffer.Ptr();
if ( aBuffer.Length() < 0 ||
(TUint)aBuffer.Length() < sizeof(SAknNotifierPackage<SAknKeyLockNotifierParams>) ||
params->iSignature != KAKNNOTIFIERSIGNATURE )
{
User::Leave( KErrArgument );
}
switch ( params->iParamData.iReason )
{
case ELockEnabled:
{
if ( !iKeyLockControl->iAutolockEnabled )
{
DoEnableKeyLock();
}
break;
}
case ELockDisabled:
{
// Protect unlocking keys if autolock emulation enabled.
// Either the application has the right capabilities, or EikSrvs does the calling.
if ( !iKeyLockControl->iAutolockEnabled ||
aMessage.HasCapability( ECapabilityWriteDeviceData ) || aMessage.HasCapability( ECapabilityTrustedUI ) )
{
DoDisableKeyLock();
}
break;
}
case EOfferKeylock:
{
DoOfferKeyLock();
break;
}
case EEnableAutoLockEmulation:
{
TInt queryActive( ESecurityQueryNotActive );
TInt autolockActive( EAutolockOff );
RProperty::Get( KPSUidStartup,
KStartupSecurityCodeQueryStatus,
queryActive );
RProperty::Get( KPSUidCoreApplicationUIs,
KCoreAppUIsAutolockStatus,
autolockActive );
// Don't activate autolock emulation if there is a sec code query up;
// our softkey CBA will come on top of its CBA if we do.
if ( queryActive == ESecurityQueryActive &&
autolockActive > EAutolockOff )
{
// Do nothing ... The emulation will be activated by Autolock
// itself in case the query is canceled.
}
else
{
// Business as usual.
NotifyStatusChange( EShowSoftNotifications );
LockKeys( ETrue );
}
break;
}
case EDisableWithoutNote:
{
// Protect unlocking keys if autolock emulation enabled.
// Either the application has the right capabilities, or EikSrvs does the calling.
if ( !iKeyLockControl->iAutolockEnabled ||
aMessage.HasCapability( ECapabilityWriteDeviceData ) || aMessage.HasCapability( ECapabilityTrustedUI ) )
{
UnlockKeys();
}
break;
}
case EEnableWithoutNote:
{
if ( !iKeyLockControl->iAutolockEnabled )
{
if ( !IsKeyLockEnabled() )
{
iKeyLockControl->EnableKeylock( EFalse );
}
}
break;
}
default:
{
break;
}
};
aMessage.Complete( KErrNone );
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Called when the keylock notifier is cancelled.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::Cancel()
{
}
// ---------------------------------------------------------------------------
// From base class MEikSrvNotifierBase2.
// Called when the active keylock notifier's data is updated.
// ---------------------------------------------------------------------------
//
TPtrC8 CAknKeyLockNotifierSubject::UpdateL( const TDesC8& aBuffer )
{
return TPtrC8( aBuffer );
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Gets the current keylock status.
// ---------------------------------------------------------------------------
//
TBool CAknKeyLockNotifierSubject::IsKeyLockEnabled()
{
return iKeyLockControl->iKeyLockEnabled;
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Notifications are always allowed here.
// ---------------------------------------------------------------------------
//
TBool CAknKeyLockNotifierSubject::AllowNotifications()
{
return iAllowNotifications;
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Disables the keylock.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::UnlockKeys()
{
if ( IsKeyLockEnabled() )
{
iKeyLockControl->AutolockEnabled( EFalse );
iKeyLockControl->DisableKeylock();
}
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Enables the keylock.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::LockKeys( TBool aAutoLockOn )
{
// We'll have to disable keylock if we are changing autolock status.
if ( IsKeyLockEnabled() && aAutoLockOn != iKeyLockControl->iAutolockEnabled )
{
iKeyLockControl->DisableKeylock(EFalse);
}
if ( !IsKeyLockEnabled() )
{
iKeyLockControl->AutolockEnabled( aAutoLockOn );
iKeyLockControl->EnableKeylock(ETrue, EFalse);
}
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Adds a keylock status change observer.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::AddObserverL( MAknKeyLockObserver* aObserver )
{
#if defined(_DEBUG)
TInt count = iObserverList->Count();
for ( TInt index = 0; index < count; index++ )
{
if ( ((*iObserverList)[index]) == aObserver )
{
Panic( EAknPanicKeyLockObserverAlreadyExists );
}
}
#endif
iObserverList->AppendL( aObserver );
// Make sure that the observer isn't obscuring the keylock CBA
ShowKeylockCba();
}
// ---------------------------------------------------------------------------
// From base class MAknKeyLockController.
// Removes a keylock status change observer.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::RemoveObserver( MAknKeyLockObserver* aObserver )
{
TInt count = iObserverList->Count();
for ( TInt index = 0; index < count; index++ )
{
if ( ((*iObserverList)[index]) == aObserver )
{
iObserverList->Delete( index );
return;
}
}
#if defined(_DEBUG)
Panic( EAknPanicKeyLockObserverNotFound );
#endif
}
// ---------------------------------------------------------------------------
// Notifies the observers of a keylock status change.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::NotifyStatusChange( TKeyLockStatus aStatus )
{
TInt count = iObserverList->Count();
for ( TInt index = count - 1; index >= 0; index-- )
{
((*iObserverList)[index])->KeyLockStatusChange( aStatus );
}
}
// ---------------------------------------------------------------------------
// Brings the keylock notifier's CBA visible.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::ShowKeylockCba()
{
if ( IsKeyLockEnabled() )
{
iKeyLockControl->ShowKeylockCba();
}
}
// ---------------------------------------------------------------------------
// Enables the keylock.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::DoEnableKeyLock()
{
if ( !IsKeyLockEnabled() )
{
iKeyLockControl->EnableKeylock();
}
}
// ---------------------------------------------------------------------------
// Disables the keylock if active.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::DoDisableKeyLock()
{
if ( IsKeyLockEnabled() )
{
iKeyLockControl->DisableKeylock();
// Attempt to display KeyActive note.
iKeyLockControl->DisplayKeyActiveNote();
}
else if ( iKeyLockControl->iOfferLockEnabled )
{
// Remove the offer key lock CBA.
iKeyLockControl->OfferTimerExpired();
}
}
// ---------------------------------------------------------------------------
// Displays the offer keylock note.
// ---------------------------------------------------------------------------
//
void CAknKeyLockNotifierSubject::DoOfferKeyLock()
{
if ( !IsKeyLockEnabled() )
{
NotifyStatusChange( EKeyLockOffered );
iKeyLockControl->OfferKeylock();
}
}