uifw/AvKon/animdllsrc/AknAnimKeySound.cpp
changeset 0 2f259fa3e83a
child 18 fcdfafb36fe7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Avkon keysound animation dll.
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDES
       
    19 #include "AknAnimKeySound.h"
       
    20 #include <eikkeysound.h>
       
    21 #include "aknanimdllstd.h"
       
    22 #include <AknKeyRotator.h>
       
    23 #include <keffactory.h>
       
    24 #include <centralrepository.h>
       
    25 
       
    26 // End key - power key related headers
       
    27 #include <featmgr.h>
       
    28 #include <e32property.h>
       
    29 #include <UikonInternalPSKeys.h>
       
    30 #include "avkoninternalpskeys.h"    // KAknIdleAppWindowGroupId
       
    31 #include <avkondomainpskeys.h>      // KAknPowerMenuStatus & KAknEndKeyEvent
       
    32 
       
    33 // This is currently nasty set dependencies, API should be moved to middleware layer asap 
       
    34 #include <ctsydomainpskeys.h> 
       
    35 #include <activeidle2domainpskeys.h>
       
    36 #include <NetworkHandlingDomainPSKeys.h>
       
    37 #include <PSVariables.h>
       
    38 
       
    39 #include <hwrmlight.h> 
       
    40 #include <tactilefeedbackserver.h>
       
    41 
       
    42 // CONSTANTS
       
    43 const TInt KShortPress(600000);
       
    44 const TInt KLongPress(1800000); // Extreme long press 2,4s - 0,6s
       
    45 
       
    46 enum TKeyEmulationAction
       
    47     {
       
    48     EDoNothing = 0,
       
    49     EEmulateNow,
       
    50     EEmulateNowPhoneCallActive,
       
    51     EEmulateNowNotificationOnTop, 
       
    52     ESetEventPending
       
    53     };
       
    54 
       
    55 // Scan codes in this table are blocked by the animdll if another key is currently being pressed
       
    56 // This prevents two keys from being pressed, but allows power key, headset and grip to still be 
       
    57 // operated.
       
    58 const TInt KBlockedKeyCodes[] =
       
    59     {
       
    60     '1',
       
    61     '2',
       
    62     '3',
       
    63     '4',
       
    64     '5',
       
    65     '6',
       
    66     '7',
       
    67     '8',
       
    68     '9',
       
    69     '0',
       
    70     EStdKeyHash,
       
    71     EStdKeyNkpAsterisk,
       
    72     EStdKeyYes,
       
    73     EStdKeyNo,
       
    74     EStdKeyApplication0,    // Apps key
       
    75     EStdKeyDevice6          // Side key
       
    76     };
       
    77 
       
    78 const TInt KBlockedKeyCodeTableSize = sizeof(KBlockedKeyCodes) / sizeof(TInt);
       
    79 
       
    80 NONSHARABLE_CLASS(CAknPendingKeyEvent): public CTimer
       
    81     {
       
    82 public:
       
    83     static CAknPendingKeyEvent* NewL(MAnimGeneralFunctions* aFucntions, TInt& aEmulatedKey);
       
    84     ~CAknPendingKeyEvent();
       
    85     TBool HandleKeyReleased(const TRawEvent &aRawEvent);
       
    86     void SetShortTimerForEvent(const TRawEvent &aRawEvent);
       
    87     void SetLongTimerForEvent(const TRawEvent &aRawEvent);
       
    88     void JustEmulateUpEvent(const TRawEvent &aRawEvent);
       
    89     TBool IsMadeUpEvent()
       
    90         {
       
    91         return iIsMadeUpEvent;
       
    92         }
       
    93     
       
    94 private:    
       
    95     CAknPendingKeyEvent(MAnimGeneralFunctions* aFucntions, TInt& aEmulatedKey);
       
    96     void RunL();
       
    97     void DoCancel();
       
    98     
       
    99     enum
       
   100         {
       
   101         EBreathe,
       
   102         EShort,
       
   103         ELong,
       
   104         EWaitingUpEvent
       
   105         };
       
   106     
       
   107     TInt iState;
       
   108     TRawEvent iPendingEvent;
       
   109     TInt& iEmulatedKey; 
       
   110     MAnimGeneralFunctions* iFunctions; 
       
   111     TBool iIsMadeUpEvent; // Indicates whether the event is self generated.
       
   112     };
       
   113 
       
   114 // REikSrvSoundServerSession implementation:
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // REikSrvSoundServerSession::Connect
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 TInt REikSrvSoundServerSession::Connect()
       
   121     {
       
   122     // Create a session with zero message slots 
       
   123     // (since we have no asycronous calls).
       
   124     TInt ret=CreateSession
       
   125         (
       
   126         __KEYSOUND_SERVER_NAME,
       
   127         TVersion( 
       
   128             KKeySoundServMajorVN, 
       
   129             KKeySoundServMinorVN, 
       
   130             KKeySoundServBuildVN ),
       
   131         1
       
   132         );
       
   133     return ret;  
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // REikSrvSoundServerSession::KeyPressed
       
   138 //
       
   139 // NB. as this is asynchronous, the cancel should be provided also, anyway we rely on that 
       
   140 // keysound server will complete all requests relatively fast so we never stall on 
       
   141 // ~CAknAnimKeySound more than tens of milliseconds.
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 void REikSrvSoundServerSession::KeyPressed( TInt aKey, TRequestStatus& aStatus, TBool aRepeat )
       
   145     {
       
   146     TIpcArgs args( aKey, aRepeat);    
       
   147     SendReceive( EKeySoundServerPlayKey, args, aStatus ); 
       
   148     }
       
   149 
       
   150 // CAknAnimKeySound implementation:
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CAknAnimKeySound::CAknAnimKeySound
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 CAknAnimKeySound::CAknAnimKeySound()
       
   157     :iEnableKeyBlock(ETrue), 
       
   158      iBlockedPointerDown(EFalse),
       
   159      iBlockKeyEvents( EFalse ),
       
   160      iBlockPointerEvents( EFalse )
       
   161     {
       
   162     iFeedback = MTactileFeedbackServer::Instance();
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CAknAnimKeySound::~CAknAnimKeySound
       
   167 // -----------------------------------------------------------------------------
       
   168 //
       
   169 CAknAnimKeySound::~CAknAnimKeySound()
       
   170     {
       
   171     if ( iFunctions )
       
   172         {
       
   173         iFunctions->GetRawEvents( EFalse );
       
   174         }
       
   175     delete iKeyRotator;
       
   176     iRotateLibrary.Close();
       
   177 
       
   178     delete iKeyEventMap;
       
   179     iKefLibrary.Close();
       
   180     
       
   181     
       
   182     delete iSoundSession;
       
   183     delete iPendingEvent;
       
   184     delete iLight;
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CAknAnimKeySound::CommandReplyL
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 TInt CAknAnimKeySound::CommandReplyL( TInt /*aOpcode*/, TAny* /*aArgs*/ )
       
   192     {
       
   193     return KErrNone;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CAknAnimKeySound::Command
       
   198 // -----------------------------------------------------------------------------
       
   199 //
       
   200 void CAknAnimKeySound::Command( TInt /*aOpcode*/, TAny* /*aArgs*/ )
       
   201     {
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CAknAnimKeySound::Animate
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 void CAknAnimKeySound::Animate( TDateTime* /*aDateTime*/ )
       
   209     {
       
   210     }
       
   211 
       
   212 // -----------------------------------------------------------------------------
       
   213 // CAknAnimKeySound::ConstructL
       
   214 // -----------------------------------------------------------------------------
       
   215 //
       
   216 void CAknAnimKeySound::ConstructL( TAny* /*aArgs*/, TBool /*aHasFocus*/ )
       
   217     {
       
   218     iFunctions->GetRawEvents( ETrue );
       
   219     
       
   220     iSoundSession = new (ELeave) CAknAsynchTonePlayer();
       
   221     
       
   222     if ( iKefLibrary.Load( KKefLibraryName ) == KErrNone )
       
   223         {
       
   224         // The function in the lookup table may leave (CreateKefMapL)
       
   225         TInt res = iKefLibrary.Lookup( KKefMapFactoryFunctionOrdinal )();
       
   226         iKeyEventMap = (CKefMap*)res;
       
   227         
       
   228         if ( !iKeyEventMap->IsKeyEventMapEnabled() )
       
   229             {
       
   230             // Key event map is disabled. Use default approach.
       
   231             delete iKeyEventMap;
       
   232             iKeyEventMap = NULL;
       
   233             iKefLibrary.Close();
       
   234             }
       
   235         else
       
   236             {
       
   237             iKeyEventMap->SetProvider( *this );
       
   238             }
       
   239         }
       
   240 
       
   241     if ( !iKeyEventMap )
       
   242         {
       
   243         if ( iRotateLibrary.Load( KAknKeyRotatorLibraryName ) == KErrNone )
       
   244             {
       
   245             // The function in the lookup table may leave (CreateAknKeyRotatorL)
       
   246             TInt res = iRotateLibrary.Lookup( KAknKeyRotatorFactoryFunctionOrdinal )();
       
   247             iKeyRotator = (CAknKeyRotator*)res;
       
   248             }
       
   249         iConnected = iSoundSession->iSoundSession.Handle() != 0;
       
   250         }
       
   251     
       
   252     FeatureManager::InitializeLibL();
       
   253     iFeatureNoPowerKey = 
       
   254         FeatureManager::FeatureSupported( KFeatureIdNoPowerkey );    
       
   255 
       
   256     if (iFeatureNoPowerKey)
       
   257         {
       
   258         iPendingEvent = CAknPendingKeyEvent::NewL(iFunctions, iNoPowerKeyScanCode);
       
   259         }
       
   260 
       
   261     FeatureManager::UnInitializeLib();
       
   262     
       
   263     // Get extension for querying and manipulating the window and screen attributes.
       
   264     iExt = reinterpret_cast<MAnimGeneralFunctionsWindowExtension*>(iFunctions->ExtendedInterface(
       
   265         MAnimGeneralFunctions::EWindowExtensionInterface)); 
       
   266             
       
   267     iLight = CHWRMLight::NewL();
       
   268     }
       
   269 
       
   270 // -----------------------------------------------------------------------------
       
   271 // CAknAnimKeySound::Redraw
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 void CAknAnimKeySound::Redraw()
       
   275     {
       
   276     }
       
   277 
       
   278 // -----------------------------------------------------------------------------
       
   279 // CAknAnimKeySound::FocusChanged
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 void CAknAnimKeySound::FocusChanged( TBool /*aState*/ )
       
   283     {
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CAknAnimKeySound::IsBlockedKeyCode
       
   288 // -----------------------------------------------------------------------------
       
   289 //
       
   290 TBool CAknAnimKeySound::IsBlockedKeyCode( TInt aScanCode )
       
   291     {
       
   292     for ( TInt ii=0; ii < KBlockedKeyCodeTableSize; ii++ )
       
   293         {
       
   294         if ( aScanCode == KBlockedKeyCodes[ii] )
       
   295             {
       
   296             return ETrue;
       
   297             }
       
   298         }
       
   299     return EFalse;
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // CAknAnimKeySound::NonBlockedKeyCode
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 TBool CAknAnimKeySound::NonBlockedKeyCode( TInt aScanCode )
       
   307     {
       
   308     // Return ETrue if this key is never blocked - typically just modifiers
       
   309     if ( aScanCode == EStdKeyLeftShift || aScanCode == EStdKeyRightShift ||
       
   310          aScanCode == EStdKeyLeftCtrl || aScanCode == EStdKeyRightCtrl ||
       
   311          aScanCode == EStdKeyLeftAlt || aScanCode == EStdKeyRightAlt ||
       
   312          aScanCode == EStdKeyLeftFunc || aScanCode == EStdKeyRightFunc )
       
   313         {
       
   314         return ETrue;
       
   315         }
       
   316     return EFalse;
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CAknAnimKeySound::IsBlockedEvent
       
   321 // HW keys and touch event interaction 
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 TBool CAknAnimKeySound::IsBlockedEvent( const TRawEvent &aRawEvent )
       
   325     {
       
   326     // Check key event exceptions
       
   327     if ( iBlockKeyEvents )
       
   328         {
       
   329         if ( aRawEvent.Type() == TRawEvent::EKeyDown || 
       
   330              aRawEvent.Type() == TRawEvent::EKeyRepeat ||
       
   331              aRawEvent.Type() == TRawEvent::EKeyUp )
       
   332             {
       
   333             // Vkb generated key event
       
   334             if ( aRawEvent.IsTip () )
       
   335                 {
       
   336                 return EFalse;
       
   337                 }
       
   338             TInt scan = aRawEvent.ScanCode() & 0xFFFF;
       
   339             if ( IsAlwaysAcceptedKey( scan ) )
       
   340                 {
       
   341                 return EFalse;
       
   342                 }
       
   343             }
       
   344         }
       
   345         
       
   346     // if key down, block pointer events and vice versa   
       
   347     switch ( aRawEvent.Type() )
       
   348         {
       
   349         case TRawEvent::EKeyDown:
       
   350             {
       
   351             if ( iBlockKeyEvents )
       
   352                 {
       
   353                 return ETrue;
       
   354                 }
       
   355             else
       
   356                 {
       
   357                 // If exception key, don't block pointer events
       
   358                 TInt scan = aRawEvent.ScanCode() & 0xFFFF;
       
   359                 if ( IsAlwaysAcceptedKey( scan ) )
       
   360                     {
       
   361                     iBlockPointerEvents = EFalse;
       
   362                     }
       
   363                 else
       
   364                     {
       
   365                     iBlockPointerEvents = ETrue;    
       
   366                     }
       
   367                 }
       
   368             break;
       
   369             }
       
   370         
       
   371         case TRawEvent::EKeyRepeat:
       
   372             {
       
   373             if ( iBlockKeyEvents )
       
   374                 {
       
   375                 return ETrue;
       
   376                 }
       
   377             break;                    
       
   378             }
       
   379         
       
   380         case TRawEvent::EKeyUp:
       
   381             {
       
   382             if ( iBlockKeyEvents )
       
   383                 {
       
   384                 return ETrue;
       
   385                 }
       
   386              else
       
   387                 {
       
   388                 iBlockPointerEvents = EFalse;
       
   389                 }
       
   390             break;                
       
   391             }
       
   392             
       
   393         case TRawEvent::EButton1Down:
       
   394             {
       
   395             if ( iBlockPointerEvents )
       
   396                 {
       
   397                 return ETrue;
       
   398                 }
       
   399             else
       
   400                 {
       
   401                 iBlockKeyEvents = ETrue;
       
   402                 }
       
   403             break;    
       
   404             }            
       
   405             
       
   406         case TRawEvent::EPointerMove:
       
   407             {
       
   408             if ( iBlockPointerEvents )
       
   409                 {
       
   410                 return ETrue;
       
   411                 }
       
   412             break;
       
   413             }
       
   414         
       
   415         case TRawEvent::EButton1Up:
       
   416             {
       
   417             if ( iBlockPointerEvents )
       
   418                 {
       
   419                 return ETrue;
       
   420                 }
       
   421             else
       
   422                 {
       
   423                 iBlockKeyEvents = EFalse;
       
   424                 }
       
   425             break;
       
   426             }
       
   427             
       
   428         default:
       
   429             break;
       
   430         }
       
   431     return EFalse;
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CAknAnimKeySound::IsAlwaysAcceptedKey
       
   436 // HW keys and touch event interaction - keys that work even if touch is active
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 TBool CAknAnimKeySound::IsAlwaysAcceptedKey( TInt aScanCode )
       
   440     {
       
   441     if ( aScanCode == EStdKeyLeftShift || aScanCode == EStdKeyRightShift ||
       
   442          aScanCode == EStdKeyLeftCtrl || aScanCode == EStdKeyRightCtrl ||
       
   443          aScanCode == EStdKeyLeftAlt || aScanCode == EStdKeyRightAlt ||
       
   444          aScanCode == EStdKeyApplication10 || // Layout switch to landscape
       
   445          aScanCode == EStdKeyApplication14 || // Layout switch to portrait
       
   446          aScanCode == EStdKeyDevice2 || // Power button
       
   447 // Device & application keys 
       
   448          ( aScanCode >= EStdKeyDevice4 && aScanCode <= EStdKeyDeviceF )||
       
   449          ( aScanCode >= EStdKeyApplication6 && aScanCode <= EStdKeyApplicationF ) ||
       
   450          ( aScanCode >= EStdKeyDevice10 && aScanCode <= EStdKeyApplication27 ) )
       
   451         {
       
   452         return ETrue;
       
   453         }
       
   454     return EFalse;   
       
   455     }
       
   456 
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 // IsIdleAppOnTop
       
   460 //
       
   461 // Returns ETrue, if the window group of Idle application is topmost.
       
   462 // -----------------------------------------------------------------------------
       
   463 //
       
   464 TBool IsIdleAppOnTop(MAnimGeneralFunctionsWindowExtension* aExt)
       
   465     {
       
   466     TBool retval = ETrue;        
       
   467     TInt idleWgId = 0;
       
   468     MAnimGeneralFunctionsWindowExtension::TWindowGroupInfo wgInfo;
       
   469     
       
   470     // Check screen having focus and the number of existing window groups.
       
   471     TInt focused = aExt->FocusScreens();
       
   472     TInt groups  = aExt->WindowGroups(focused);
       
   473     
       
   474     // Get the idle application window group id.
       
   475     TInt err = RProperty::Get(KPSUidAvkonInternal, KAknIdleAppWindowGroupId, idleWgId);
       
   476     
       
   477     // If there is an error fetching the window group id, it is safer to assume that
       
   478     // Idle application is on top. The power menu will be shown then.    
       
   479     if(!err && idleWgId != -1)
       
   480         {
       
   481         // Got valid window group id. Go through the window group list and find if there is a 
       
   482         // focusable group on top of Idle.
       
   483         for (TInt i = 0; i < groups; i++)
       
   484             {
       
   485             const TBool exist = aExt->WindowGroupInfo(wgInfo, focused, i);
       
   486             
       
   487             if(exist)
       
   488                 {
       
   489                 if (wgInfo.iId == idleWgId)
       
   490                     {
       
   491                     // Idle app is on top.
       
   492                     break;
       
   493                     }
       
   494                 else if (wgInfo.IsFocusable())
       
   495                     {
       
   496                     // We have some notification on top of the idle app.
       
   497                     retval = EFalse;
       
   498                     break;
       
   499                     }
       
   500                 }
       
   501             } 
       
   502         }      
       
   503     else
       
   504         {
       
   505 #ifdef _DEBUG
       
   506         RDebug::Print(_L("AknAnimKeySound:IsIdleAppOnTop() - Error fetching idleWgId, id=%d"), err);         
       
   507 #endif                 
       
   508         }
       
   509     return retval;
       
   510     }
       
   511 
       
   512 // -----------------------------------------------------------------------------
       
   513 // EmulateEndKeyL
       
   514 //
       
   515 // Emulates end key. Used if the device has combined power and end key.
       
   516 // -----------------------------------------------------------------------------
       
   517 //
       
   518 void EmulateEndKeyL(TKeyEmulationAction& aResult, const TRawEvent &aRawEvent, 
       
   519     /*TInt& aEmulatedScanCode,*/ MAnimGeneralFunctionsWindowExtension* aExt)
       
   520     {
       
   521     aResult = EDoNothing;
       
   522     if (aRawEvent.Type() == TRawEvent::EKeyDown)
       
   523         {
       
   524         TInt ps(0), startupOk(0), idle(0);
       
   525 
       
   526         // If system is not in idle or there are calls ongoing, then end key ought to be generated.
       
   527         User::LeaveIfError( RProperty::Get( KPSUidCtsyCallInformation, KCTsyCallState, ps ) );
       
   528         User::LeaveIfError( RProperty::Get( KPSUidAiInformation, KActiveIdleState, idle ) );
       
   529         User::LeaveIfError( RProperty::Get( KPSUidUikon, KUikGlobalNotesAllowed, startupOk ) );
       
   530 
       
   531         RDebug::Print(_L("call: %d, idle %d, notes %d"), ps, idle, startupOk);
       
   532 
       
   533         // Call state not yet initialized or startup not yet complete but no emergency call ongoing.
       
   534         if (ps == EPSCTsyCallStateUninitialized || 
       
   535            (ps == EPSCTsyCallStateNone && !startupOk) )
       
   536             {
       
   537             return;
       
   538             }
       
   539         
       
   540         if ( idle == EPSAiForeground )
       
   541             { 
       
   542             // Notify active idle plugins that combined end key / power key has been pressed.
       
   543             RProperty::Set(KPSUidAvkonDomain, KAknEndKeyEvent, 1); 
       
   544             }
       
   545         
       
   546         if ( ps != EPSCTsyCallStateNone )
       
   547             {
       
   548             // A phone call is active.
       
   549             aResult = EEmulateNowPhoneCallActive;
       
   550             }
       
   551         else if ( idle != EPSAiForeground )
       
   552             {
       
   553             // We are not in idle view. No active phone calls.
       
   554             aResult = EEmulateNow;
       
   555             }
       
   556         else
       
   557             {
       
   558             // We are in idle view with no active phone calls. 
       
   559             TInt powerMenuActive(0);
       
   560                         
       
   561             // If power menu is active, do not check windows on top of the Idle app, short power
       
   562             // key presses must change the item in the power menu, not to close the power menu.
       
   563             User::LeaveIfError(RProperty::Get(KPSUidAvkonDomain, KAknPowerMenuStatus, powerMenuActive));
       
   564             if(!powerMenuActive)
       
   565                 {
       
   566                 // If there is a notification (window) on top of idle, the event is changed to 
       
   567                 // end key for closing it. Otherwise we continue normally.
       
   568                 if(!IsIdleAppOnTop(aExt))
       
   569                     {
       
   570                     aResult = EEmulateNowNotificationOnTop;
       
   571                     return;
       
   572                     }
       
   573                 }
       
   574             
       
   575             // Make bearer resolution.
       
   576             User::LeaveIfError(RProperty::Get(KPSUidNetworkInfo, KNWTelephonyNetworkMode, ps)); 
       
   577             if (ps == ENWNetworkModeWcdma)
       
   578                 {
       
   579                 User::LeaveIfError(RProperty::Get(KUidSystemCategory, KPSUidWcdmaStatusValue, ps));
       
   580                 if (ps != EPSWcdmaStatusUninitialized && ps != EPSWcdmaUnattached && ps != KErrUnknown)
       
   581                     {
       
   582                     // Wcdma is active (or attached).
       
   583                     aResult = ESetEventPending;
       
   584                     }        
       
   585                 else
       
   586                     {
       
   587                     // Wcdma is not active, do nothing.
       
   588                     }
       
   589                 } 
       
   590             else // gsm et als
       
   591                 {
       
   592                 User::LeaveIfError(RProperty::Get(KUidSystemCategory, KPSUidGprsStatusValue, ps));
       
   593                 if (ps != EPSGprsUnattached && ps != EPSGprsStatusUninitialized && ps != KErrUnknown)
       
   594                     {
       
   595                     // Gprs is active (or attached).                    
       
   596                     aResult = ESetEventPending;
       
   597                     }
       
   598                 else
       
   599                     {
       
   600                     // Gprs is not active, do nothing.
       
   601                     }
       
   602                 }
       
   603             } 
       
   604         }
       
   605     }
       
   606 
       
   607 // -----------------------------------------------------------------------------
       
   608 // EmulateEndKey
       
   609 //
       
   610 // Emulates end key. Used if the device has combined power and end key.
       
   611 // -----------------------------------------------------------------------------
       
   612 //
       
   613 TKeyEmulationAction EmulateEndKey(const TRawEvent &aRawEvent, /*TInt& aEmulatedScanCode,*/
       
   614     MAnimGeneralFunctionsWindowExtension* aExt)
       
   615     {
       
   616     TKeyEmulationAction result(EDoNothing);
       
   617         {
       
   618         TRAP_IGNORE(EmulateEndKeyL(result, aRawEvent/*, aEmulatedScanCode*/, aExt));
       
   619         }
       
   620     return result;    
       
   621     }
       
   622 
       
   623 // -----------------------------------------------------------------------------
       
   624 // CAknAnimKeySound::OfferRawEvent
       
   625 // -----------------------------------------------------------------------------
       
   626 //
       
   627 TBool CAknAnimKeySound::OfferRawEvent(const TRawEvent &aRawEvent)
       
   628     {
       
   629     // Check HW and touch interaction
       
   630     if ( IsBlockedEvent ( aRawEvent ) )
       
   631         {
       
   632         return ETrue;
       
   633         }
       
   634  
       
   635     // Check key blocking enable / disable codes:
       
   636     if ( (TAknKeySoundOpcode)( aRawEvent.Type() ) == EEnableKeyBlock )
       
   637         {
       
   638         iEnableKeyBlock = ETrue;
       
   639         return ETrue;
       
   640         }
       
   641     if ( (TAknKeySoundOpcode)( aRawEvent.Type() ) == EDisableKeyBlock )
       
   642         {
       
   643         iEnableKeyBlock = EFalse;
       
   644         return ETrue;
       
   645         }
       
   646 
       
   647     if (iFeatureNoPowerKey && !iPendingEvent->IsMadeUpEvent() 
       
   648         && (aRawEvent.Type () == TRawEvent::EKeyDown || aRawEvent.Type () == TRawEvent::EKeyUp ))
       
   649         {
       
   650         if (aRawEvent.ScanCode() != EStdKeyDevice2)
       
   651             {
       
   652             if (aRawEvent.ScanCode() != iNoPowerKeyScanCode) // handle here so it won't fall through
       
   653                 {
       
   654                 iPendingEvent->Cancel();    
       
   655                 }
       
   656             }
       
   657         else if (iPendingEvent->IsActive())
       
   658             {
       
   659             if (iPendingEvent->HandleKeyReleased(aRawEvent))
       
   660                 {
       
   661                 return ETrue;
       
   662                 }
       
   663             // else let it just fall trough of KEF also            
       
   664             }
       
   665         else
       
   666             {
       
   667             // evaluate now
       
   668             TInt action = EmulateEndKey(aRawEvent, iExt);
       
   669             
       
   670             switch(action)
       
   671                 {
       
   672                 case EEmulateNow:
       
   673                 case EEmulateNowPhoneCallActive:
       
   674                 case EEmulateNowNotificationOnTop:
       
   675                     {
       
   676                     TRawEvent newEvent(aRawEvent);
       
   677                     newEvent.Set( aRawEvent.Type(), EStdKeyNo );
       
   678                     iFunctions->PostRawEvent(newEvent);
       
   679                         
       
   680                     if (action == EEmulateNow)
       
   681                         {
       
   682                         // Start timer for extra long key press (both keys generated).
       
   683                         iPendingEvent->SetLongTimerForEvent(newEvent);
       
   684                         }
       
   685                     else
       
   686                         {
       
   687                         // No timers are set. A long power key press must not switch the phone off
       
   688                         // if there is an active phone call or a notification is on top of the Idle app. 
       
   689                         // Only the call needs to be disconnected or notification closed.
       
   690                         iPendingEvent->JustEmulateUpEvent(newEvent); 
       
   691                         }
       
   692                     return ETrue;            
       
   693                     }            
       
   694                 case ESetEventPending:
       
   695                     {
       
   696                     // set short timer for down event
       
   697                     iPendingEvent->SetShortTimerForEvent(aRawEvent);
       
   698                     return ETrue; 
       
   699                     }
       
   700                 default:
       
   701                     break;            
       
   702                 }
       
   703             }
       
   704         }
       
   705 
       
   706     // If key event map is in use, then forward events.
       
   707     if ( iKeyEventMap )
       
   708         {
       
   709         if ( iKeyEventMap->OfferRawEvent( aRawEvent, EFalse ) )
       
   710             {
       
   711             return ETrue;
       
   712             }
       
   713         }
       
   714     else
       
   715         {
       
   716         // If key rotator is in use, then forward key events.
       
   717         // Note that key event map and key rotator cannot be in use at
       
   718         // the same time.
       
   719         if( iKeyRotator )
       
   720             {
       
   721             if ( iKeyRotator->CheckRotation( aRawEvent, *iFunctions ) )
       
   722                 {
       
   723                 return ETrue;
       
   724                 }
       
   725             }
       
   726         }
       
   727 
       
   728     // If key event map is disabled, then use default approach.
       
   729     // Also, if key event map did not consume event, handle blocking here.
       
   730     // However, key sounds are handled in key event map.
       
   731    
       
   732     // Then, check the key blocking
       
   733     TBool blockEvent = EFalse;
       
   734     
       
   735     switch ( aRawEvent.Type() )
       
   736         {
       
   737         case TRawEvent::EKeyDown:
       
   738             {
       
   739             TInt scan = aRawEvent.ScanCode() & 0xFFFF;
       
   740             if ( !NonBlockedKeyCode( scan ) 
       
   741                 && iKeyPressed && iEnableKeyBlock && IsBlockedKeyCode( scan ) )
       
   742                 {
       
   743                 blockEvent = ETrue;
       
   744                 }
       
   745             else
       
   746                 {
       
   747                 if ( iConnected ) // to avoid playing tones twice with KEF
       
   748                     {
       
   749                     iSoundSession->KeyPressed( scan );
       
   750                     }
       
   751                 if ( !NonBlockedKeyCode( scan ) )
       
   752                     {
       
   753                     iKeyPressed = scan;
       
   754                     }
       
   755                 else
       
   756                     {
       
   757                     iKeyPressed = 0;
       
   758                     }
       
   759                 }
       
   760             }
       
   761             break;
       
   762 
       
   763         case TRawEvent::EKeyRepeat:
       
   764             {
       
   765             TInt scan = aRawEvent.ScanCode() & 0xFFFF;
       
   766             if ( !NonBlockedKeyCode( scan ) && iKeyPressed != scan && 
       
   767                  iEnableKeyBlock && IsBlockedKeyCode( scan ) )
       
   768                 {
       
   769                 // If down event is not passed forward, then 
       
   770                 // repeat events are not passed either.
       
   771                 blockEvent = ETrue;
       
   772                 }
       
   773             }
       
   774             break;
       
   775             
       
   776         case TRawEvent::EKeyUp:
       
   777             {
       
   778             TInt scan = aRawEvent.ScanCode() & 0xFFFF;
       
   779             if ( !NonBlockedKeyCode( scan ) && iKeyPressed != scan && 
       
   780                  iEnableKeyBlock && IsBlockedKeyCode( scan ) )
       
   781                 {
       
   782                 // Do not need to block key-up events - there's not a problem 
       
   783                 // if there's an unexpected key-up events delivery to an app
       
   784                 }
       
   785             else
       
   786                 {
       
   787                 iKeyPressed = 0;
       
   788                 }
       
   789             }
       
   790             break;
       
   791         
       
   792         // If pointer down is received when the lights are out,
       
   793         // all pointer events are blocked until next pointer down.    
       
   794                 case TRawEvent::EButton1Down:
       
   795             {
       
   796             if( iBlockedPointerDown )
       
   797                 {
       
   798                 iBlockedPointerDown = EFalse;
       
   799                 }
       
   800 
       
   801             if( iLight && iLight->LightStatus( CHWRMLight::EPrimaryDisplay ) == CHWRMLight::ELightOff )
       
   802                 {
       
   803                 blockEvent = ETrue;
       
   804                 iBlockedPointerDown = ETrue;
       
   805                 }
       
   806             }
       
   807             break;
       
   808         case TRawEvent::EButton1Up:
       
   809         case TRawEvent::EPointerMove:
       
   810             {
       
   811             if( iBlockedPointerDown )
       
   812                 {
       
   813                 blockEvent = ETrue;
       
   814                 }
       
   815             }
       
   816             break;
       
   817 
       
   818         default:
       
   819             break;
       
   820         }
       
   821 
       
   822     return blockEvent;
       
   823     }
       
   824 
       
   825 // -----------------------------------------------------------------------------
       
   826 // CAknAnimKeySound::KefPostRawEvent
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 void CAknAnimKeySound::KefPostRawEvent(const TRawEvent& aRawEvent) const
       
   830     {
       
   831     iFunctions->PostRawEvent( aRawEvent );
       
   832     }
       
   833 
       
   834 // -----------------------------------------------------------------------------
       
   835 // CAknAnimKeySound::KefPostKeyEvent
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 void CAknAnimKeySound::KefPostKeyEvent(const TKeyEvent& aKeyEvent) const
       
   839     {
       
   840     iFunctions->PostKeyEvent( aKeyEvent );
       
   841     }
       
   842 
       
   843 // -----------------------------------------------------------------------------
       
   844 // CAknAnimKeySound::KefGenerateKeySound
       
   845 // -----------------------------------------------------------------------------
       
   846 //
       
   847 void CAknAnimKeySound::KefGenerateKeySound( TInt aKey )
       
   848     {
       
   849     iSoundSession->KeyPressed( aKey, EFalse );
       
   850     }
       
   851 
       
   852 // -----------------------------------------------------------------------------
       
   853 // CAknAnimKeySound::KefGenerateFeedback
       
   854 // -----------------------------------------------------------------------------
       
   855 //
       
   856 void CAknAnimKeySound::KefGenerateFeedback( TUint16 aFeedback )
       
   857     {
       
   858     if ( iFeedback )
       
   859         {
       
   860         iFeedback->InstantFeedback( (TTouchLogicalFeedback)aFeedback );
       
   861         }
       
   862     }
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // CAknPendingKeyEvent::NewL
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 CAknPendingKeyEvent* CAknPendingKeyEvent::NewL(MAnimGeneralFunctions* aFunctions, TInt& aEmulatedKey)
       
   869     {
       
   870     CAknPendingKeyEvent* me = new (ELeave) CAknPendingKeyEvent(aFunctions, aEmulatedKey);
       
   871     CleanupStack::PushL(me);
       
   872     me->ConstructL();
       
   873     CleanupStack::Pop();
       
   874     return me;
       
   875     }
       
   876 
       
   877 // -----------------------------------------------------------------------------
       
   878 // CAknPendingKeyEvent::CAknPendingKeyEvent
       
   879 // -----------------------------------------------------------------------------
       
   880 //
       
   881 CAknPendingKeyEvent::CAknPendingKeyEvent(MAnimGeneralFunctions* aFunctions, TInt& aEmulatedKey)
       
   882     :CTimer(CActive::EPriorityHigh),iEmulatedKey(aEmulatedKey),iFunctions(aFunctions)
       
   883     {
       
   884     CActiveScheduler::Add(this);
       
   885     }
       
   886 
       
   887 // -----------------------------------------------------------------------------
       
   888 // CAknPendingKeyEvent::~CAknPendingKeyEvent
       
   889 // -----------------------------------------------------------------------------
       
   890 //
       
   891 CAknPendingKeyEvent::~CAknPendingKeyEvent()
       
   892     {
       
   893     }
       
   894 
       
   895 // -----------------------------------------------------------------------------
       
   896 // CAknPendingKeyEvent::HandleKeyReleased
       
   897 // -----------------------------------------------------------------------------
       
   898 //
       
   899 TBool CAknPendingKeyEvent::HandleKeyReleased(const TRawEvent& /*aRawEvent*/)
       
   900     {
       
   901     TBool result(EFalse);
       
   902     TInt state = iState;
       
   903     Cancel();
       
   904     if (state == EShort)
       
   905         {
       
   906         // generate short powerkey
       
   907         iIsMadeUpEvent = ETrue;
       
   908         iFunctions->PostRawEvent(iPendingEvent); // contains powerkey down
       
   909         iIsMadeUpEvent = EFalse;
       
   910 
       
   911         result = EFalse; // let the up event go through
       
   912         }
       
   913     else if (state == ELong)
       
   914         {
       
   915         result = ETrue; // just block the original
       
   916         }
       
   917         
       
   918     else if (state == EWaitingUpEvent)
       
   919         {
       
   920         result = ETrue; // just block the original
       
   921         }
       
   922     
       
   923     return result;
       
   924     }
       
   925 
       
   926 // -----------------------------------------------------------------------------
       
   927 // CAknPendingKeyEvent::SetShortTimerForEvent
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 void CAknPendingKeyEvent::SetShortTimerForEvent(const TRawEvent &aRawEvent)
       
   931     {
       
   932     iPendingEvent = aRawEvent;
       
   933     After(KShortPress);
       
   934     iState = EShort;
       
   935     }
       
   936 
       
   937 // -----------------------------------------------------------------------------
       
   938 // CAknPendingKeyEvent::SetLongTimerForEvent
       
   939 // -----------------------------------------------------------------------------
       
   940 //
       
   941 void CAknPendingKeyEvent::SetLongTimerForEvent(const TRawEvent &aRawEvent)
       
   942     {
       
   943     iEmulatedKey = aRawEvent.ScanCode();
       
   944     iPendingEvent = aRawEvent;
       
   945     After(KLongPress); 
       
   946     iState = ELong;    
       
   947     }
       
   948 
       
   949 // -----------------------------------------------------------------------------
       
   950 // CAknPendingKeyEvent::JustEmulateUpEvent
       
   951 // -----------------------------------------------------------------------------
       
   952 //
       
   953 void CAknPendingKeyEvent::JustEmulateUpEvent(const TRawEvent &aRawEvent)
       
   954     {
       
   955     if (!IsActive())
       
   956         {
       
   957         iEmulatedKey = aRawEvent.ScanCode();
       
   958         iPendingEvent = aRawEvent;
       
   959         iStatus = KRequestPending;
       
   960         SetActive();
       
   961         iState = EWaitingUpEvent;
       
   962         }
       
   963     }
       
   964 
       
   965 // -----------------------------------------------------------------------------
       
   966 // CAknPendingKeyEvent::RunL
       
   967 // -----------------------------------------------------------------------------
       
   968 //
       
   969 void CAknPendingKeyEvent::RunL()
       
   970     {
       
   971     switch(iState)
       
   972         {
       
   973         case EShort: // Generate end-key and start waiting again
       
   974             {
       
   975             iEmulatedKey = EStdKeyEnd; // please note that this is not standard end-key !!
       
   976             
       
   977             iIsMadeUpEvent = ETrue;
       
   978             iPendingEvent.Set(TRawEvent::EKeyDown,iEmulatedKey);
       
   979             iFunctions->PostRawEvent(iPendingEvent);
       
   980             iIsMadeUpEvent = EFalse;
       
   981             
       
   982             After(KLongPress); 
       
   983             iState = ELong;    
       
   984             break;
       
   985             }  
       
   986          
       
   987         case ELong:
       
   988             {
       
   989             iIsMadeUpEvent = ETrue;
       
   990             if (iEmulatedKey != EKeyNull)
       
   991                 {
       
   992                 iPendingEvent.Set(TRawEvent::EKeyUp,iEmulatedKey);
       
   993                 iFunctions->PostRawEvent(iPendingEvent);
       
   994                 iEmulatedKey = EKeyNull;
       
   995                 }
       
   996 
       
   997             iPendingEvent.Set(TRawEvent::EKeyDown,EStdKeyDevice2);
       
   998             iFunctions->PostRawEvent(iPendingEvent);
       
   999             iIsMadeUpEvent = EFalse;
       
  1000             
       
  1001             iState = EBreathe;    
       
  1002             break;
       
  1003             }  
       
  1004          
       
  1005         default:
       
  1006             break;
       
  1007         }
       
  1008     }
       
  1009     
       
  1010 // -----------------------------------------------------------------------------
       
  1011 // CAknPendingKeyEvent::DoCancel
       
  1012 // -----------------------------------------------------------------------------
       
  1013 //    
       
  1014 void CAknPendingKeyEvent::DoCancel()
       
  1015     {
       
  1016     if (iEmulatedKey != EKeyNull)
       
  1017         {
       
  1018         iIsMadeUpEvent = ETrue;
       
  1019         iPendingEvent.Set(TRawEvent::EKeyUp,iEmulatedKey);
       
  1020         iFunctions->PostRawEvent(iPendingEvent);
       
  1021         iEmulatedKey = EKeyNull;
       
  1022         iIsMadeUpEvent = EFalse;
       
  1023         }
       
  1024   
       
  1025     if (iState == EWaitingUpEvent)
       
  1026         {
       
  1027         TRequestStatus* sptr = &iStatus;
       
  1028         User::RequestComplete(sptr, KErrNone);
       
  1029         }
       
  1030     else
       
  1031         {
       
  1032         CTimer::DoCancel();
       
  1033         }
       
  1034         
       
  1035     iState = EBreathe;  
       
  1036     }
       
  1037 
       
  1038 // End of File