mediakeys/KeyPublisherPlugin/src/KeyPublisher.cpp
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mediakeys/KeyPublisherPlugin/src/KeyPublisher.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,439 @@
+/*
+* Copyright (c) 2005 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: 
+*       Animation plugin implementation file
+*       
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <e32cmn.h>
+#include <mediakeysinternalpskeys.h>
+#include <mmkeybearerscancodes.h>
+#include <remconcoreapi.h>
+#include <uikon.hrh>
+
+#include "KeyPublisher.h"
+
+// CONSTANTS
+
+const TInt KScanCodeMask = 0xFFFF;
+
+#if defined(__WINS__)
+const TInt KVolumeUpKeyEmulator   = 0xAC;
+const TInt KVolumeDownKeyEmulator = 0xAD;
+#endif
+// Change these values once peoblem with keys is fixed
+const TInt KVolumeUpKeyHardware   = EStdKeyIncVolume;   //0xa3; 
+const TInt KVolumeDownKeyHardware = EStdKeyDecVolume;  //0xa2; 
+
+const TInt KMusicPlayHarware     = EStdKeyApplication2;
+const TInt KMusicStopHarware     = EStdKeyApplication3;
+const TInt KMusicForwardHardware = EStdKeyApplication4;
+const TInt KMusicRewindHardware  = EStdKeyApplication5;
+
+// Scan codes in this table are blocked by the Key Publisher Anim plugin
+// Table KBlockedKeyCodes[] and KBlockedKeyCodesEvents[][3] must have same 
+// number of rows and match correspondingly
+const TInt KBlockedKeyCodes[]=
+    {
+#if defined(__WINS__)    
+    /*0*/KVolumeUpKeyEmulator,
+    /*1*/KVolumeDownKeyEmulator,
+#endif
+    /*2*/KVolumeUpKeyHardware,
+    /*3*/KVolumeDownKeyHardware,
+
+    /*4*/ KMusicPlayHarware,    
+    /*5*/ KMusicStopHarware,    
+    /*6*/ KMusicForwardHardware,
+    /*7*/ KMusicRewindHardware 
+
+    };
+const TInt KBlockedKeyCodesEvents[][3]=
+    {     /* Press - 0 */       /* Release - 1 */      /* Click - 2 */
+#if defined(__WINS__)    
+    /*0*/{KPSVolumeUpPressed,   KPSVolumeUpReleased,   KPSVolumeUpClicked },
+    /*1*/{KPSVolumeDownPressed, KPSVolumeDownReleased, KPSVolumeDownClicked },
+#endif
+    /*2*/{KPSVolumeUpPressed,   KPSVolumeUpReleased,   KPSVolumeUpClicked },
+    /*3*/{KPSVolumeDownPressed, KPSVolumeDownReleased, KPSVolumeDownClicked }, 
+
+    /*4*/{EPlayPressed,         EPlayReleased,         EPlayClicked },
+    /*5*/{EStopPressed,         EStopReleased,         EStopClicked },
+    /*6*/{EFastForwardPressed,  EFastForwardReleased,  EForwardClicked },
+    /*7*/{ERewindPressed,       ERewindReleased,       EBackwardClicked }
+
+    };
+
+const TInt KBlockedKeyCodeTableSize = sizeof(KBlockedKeyCodes) / sizeof(TInt);
+
+const TInt KTimerMilliSecond = 1000; // in micro seconds
+
+_LIT_SECURITY_POLICY_C1(KKeyPublisherReadPolicy,  ECapability_None);
+_LIT_SECURITY_POLICY_C1(KKeyPublisherWritePolicy, ECapabilityWriteDeviceData);
+
+// Following constants can subject change if duration is not suitable
+
+const TInt KFirstTimerExpiryInterval = 600 * KTimerMilliSecond; // 600mSec
+// For second time onwards ,the duration of the time interval, is below
+// Should not be grater than 1 Minute
+const TInt KTimerExpiryInterval      = 500 * KTimerMilliSecond; // 500mSec
+
+// -----------------------------------------------------------------------
+// CKeyPublisher::CKeyPublisher
+// Description: Constuctor
+// -----------------------------------------------------------------------
+//
+CKeyPublisher::CKeyPublisher()
+: iTimerStarted (EFalse) ,iPressEventSent(EFalse) ,iReleaseEventSent(ETrue),
+  iTimerCount(0), iConnected(EFalse)
+    {
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::~CKeyPublisher
+// Description: Destructor
+// -----------------------------------------------------------------------
+//
+CKeyPublisher::~CKeyPublisher()
+    {
+    
+    iSoundSession.Close();
+    
+    if (iFunctions)
+        {
+        //switch OFF the animation raw event receiving 
+        iFunctions->GetRawEvents(EFalse);
+        }
+    if(iTimer)
+        {
+        delete iTimer;
+        }
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::ConstructL   (part of CWindowAnim)
+// Description: Enable the Raw Event handling from Win server. and 
+//              create timer (not starting)
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::ConstructL(TAny* /*aArgs*/, TBool /*aHasFocus*/)
+    {
+    
+    /* iFunction: protected member of CAnim /CWindowAnim
+     * Pointer to a class containing functions implemented by the window 
+     * server. These are available to any CAnim derived class. Note that 
+     * this value is automatically set for you by the animation framework. 
+     * we do not need to assign a value to this pointer.
+     */
+    
+    /* This function switches animation raw event handling on and off. If 
+     * raw event handling is switched on(ETrue), then raw events, 
+     * e.g. pen events, key presses, power events etc., are all offered 
+     * to the animation event handling code - MEventHandler::OfferRawEventL().
+     */ 
+    iFunctions->GetRawEvents(ETrue);
+    
+    TInt error = iSoundSession.Connect();
+    if (error == KErrNone)
+        {
+        iConnected = ETrue;
+		}
+    
+    // Timer for implementing Pressed/Released/Clicked feature.
+    iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+    
+    //Define the P&S for Volume keys and Media Keys
+    RProperty::Define(KPSUidMediaKeysEventNotifier, KMediaKeysVolumeKeyEvent, 
+           RProperty::EInt, KKeyPublisherReadPolicy, KKeyPublisherWritePolicy);
+    RProperty::Define(KPSUidMediaKeysEventNotifier, KMediaKeysControlKeyEvent,
+           RProperty::EInt, KKeyPublisherReadPolicy, KKeyPublisherWritePolicy);
+    // Define Vol Sync Notifier in P & S
+    RProperty::Define(KPSUidMediaKeysEventNotifier,KMediaKeysCurrentVolume, 
+           RProperty::EInt, KKeyPublisherReadPolicy, KKeyPublisherWritePolicy);
+    // Define P&S Key for Volume keys from Accessory device
+    RProperty::Define(KPSUidMediaKeysEventNotifier,KMediaKeysAccessoryVolumeEvent, 
+           RProperty::EInt, KKeyPublisherReadPolicy, KKeyPublisherWritePolicy);
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::IsBlockedKeyCode 
+// Description: Search the list of blocked keys by comparing scan codes
+// return : ETrue if key is blocked, else EFalse
+// -----------------------------------------------------------------------
+//
+TBool CKeyPublisher::IsBlockedKeyCode(TInt aScanCode)
+    {
+    for (TInt index=0; index < KBlockedKeyCodeTableSize; index++)
+        {
+        if (aScanCode == KBlockedKeyCodes[index])
+            {
+            // Found the Key 
+            return ETrue;
+            }
+        }
+    // Not found
+    return EFalse;
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::GetEnumVal
+// Description: Based on the scancode and event, find the Enum value(which
+//              are declared in the TRemConCoreApiButtonAction).
+//              MMBearerPlugin will decript this enum value.
+// return : 
+// -----------------------------------------------------------------------
+//
+TInt CKeyPublisher::GetEnumVal(TInt aScanCode, 
+                               TRemConCoreApiButtonAction aEvent)
+    {
+    TInt result = KPSVolumeNoKey;
+    TInt index;
+
+    // Find the Index of the Scan code in the KBlockedKeyCodes[] 
+    // and use the same index in KBlockedKeyCodesEvents[][] 
+    // for getting enum values
+    for (index=0; index < KBlockedKeyCodeTableSize; index++)
+        {
+        if (aScanCode == KBlockedKeyCodes[index])
+            {
+            break;
+            }
+        }
+
+    if (index == KBlockedKeyCodeTableSize)
+    {
+        // Not found 
+        return result;
+    }
+
+    result = KBlockedKeyCodesEvents[index][aEvent];
+    return result;
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::PublishEvent
+// Description: Publish the event to P&S based on the Scancode, event
+// return : 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::PublishEvent(TInt aScanCode, 
+                                 TRemConCoreApiButtonAction aEvent)
+    {
+    TInt uidMMKey;
+    
+    if ( 
+#if defined(__WINS__)        
+         (aScanCode == KVolumeUpKeyEmulator)   ||
+         (aScanCode == KVolumeDownKeyEmulator) ||
+#endif         
+         (aScanCode == KVolumeUpKeyHardware)   ||
+         (aScanCode == KVolumeDownKeyHardware)  
+       )
+        {
+        uidMMKey = KMediaKeysVolumeKeyEvent; // Volume Keys - Up / down
+        }
+    else
+        {
+        uidMMKey = KMediaKeysControlKeyEvent; //Media Keys - play ,stop ,etc
+        }
+
+    iProperty.Set(KPSUidMediaKeysEventNotifier,
+                  uidMMKey,
+                  GetEnumVal(aScanCode, aEvent));
+
+    }   
+    
+// -----------------------------------------------------------------------
+// CKeyPublisher::OfferRawEvent
+// Description: This function starts getting called when animation raw 
+//              event is switched on by calling GetRawEvents(ETrue)
+// return : ETrue  - if key is handled and blocks it to applications
+//          EFalse - if not handled here, Apps/other anim plugins will 
+//               receive this key event.
+// -----------------------------------------------------------------------
+//
+TBool CKeyPublisher::OfferRawEvent(const TRawEvent &aRawEvent)
+    {
+    TBool returnValue = EFalse;        // Key not blocked
+    TInt scan;
+    
+    switch (aRawEvent.Type())
+        {
+        case TRawEvent::EKeyDown:
+            {
+            scan = aRawEvent.ScanCode() & KScanCodeMask;
+            
+            if (IsBlockedKeyCode(scan))
+                {
+                if (iConnected)
+                    {
+                    iSoundSession.KeyPressed(scan);  	
+                    }
+                
+                if ((! iTimerStarted) && (iReleaseEventSent))
+                    {
+                    
+                    if ((scan != KMusicForwardHardware) && (scan != KMusicRewindHardware))
+                    {
+	                    // Send Clicked Event
+	                    PublishEvent(scan,ERemConCoreApiButtonClick);
+                    }
+
+                    //Start Timer
+                    iTimer->Start(KFirstTimerExpiryInterval,
+                                  KTimerExpiryInterval, 
+                                  TCallBack(TimerCallback, this));
+                    iTimerStarted  = ETrue;
+                    iPrevScanCode    = scan;
+                    iPressEventSent = EFalse;
+                    returnValue     = ETrue; // Block   
+                    iReleaseEventSent = EFalse; // For blocking multiple key
+                                                // presses
+                    }
+                }
+            }
+            break;
+        case TRawEvent::EKeyUp:
+            {
+            scan = aRawEvent.ScanCode() & KScanCodeMask;
+
+            if ((iPrevScanCode == scan) && IsBlockedKeyCode(scan))
+                { 
+            
+                // Clicked Scenario
+                if ( iPressEventSent == EFalse ) 
+                    {
+                    
+                    if ((iPrevScanCode == KMusicForwardHardware) ||  
+                        (iPrevScanCode == KMusicRewindHardware))
+                    {
+	                    // Send Clicked Event
+	                    PublishEvent(iPrevScanCode, ERemConCoreApiButtonClick);
+                    }
+                    
+                    // Since Click event has been sent when pressed down,
+                    // (except Frwd & Rewind)
+                    // Just stop the timer
+                    if (iTimerStarted)
+                        {
+                        iTimer->Cancel();
+                        iTimerStarted  = EFalse;
+                        }
+                    iReleaseEventSent = ETrue;
+                    iPrevScanCode     = 0;
+                    returnValue       = ETrue; //Block it
+                    }
+                else  // Released Scenario
+                    {
+                    PublishEvent(scan,ERemConCoreApiButtonRelease);
+
+                    iPrevScanCode   = 0;
+                    iPressEventSent = EFalse;
+                    returnValue     = ETrue; //Block it
+                    iReleaseEventSent = ETrue;
+
+                    }
+                    
+                } // end of if ((iPrevScanCode == scan) && IsBlockedK...
+            }
+            break;
+        default:
+            break;
+        }
+    return returnValue; // to allow the event to be passed back to app
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::HandleTimerEvent
+// Description: When Timer is expired, this function is called from 
+//              callback function. If the timer is expired for the first
+//              time then KeyPressed event is published to P&S. And 
+//              second and further expires, only count is incremented.
+//              Once the count reaches some predefined value, Released 
+//              Key event is posted to P&S. and timer is switched off.
+// return : 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::HandleTimerEvent()
+    {
+    
+    // Send Pressed Key Event
+    PublishEvent(iPrevScanCode,ERemConCoreApiButtonPress);  
+    iPressEventSent = ETrue;
+    iTimer->Cancel();
+    iTimerStarted  = EFalse;
+
+    }
+
+// -----------------------------------------------------------------------
+// CKeyPublisher::TimerCallback
+// Description: When Timer is expired, this function is called 
+// return : 
+// -----------------------------------------------------------------------
+//
+TInt CKeyPublisher::TimerCallback(TAny* aThis)
+    {
+    
+    //STATIC_CAST(CKeyPublisher*,aThis)->HandleTimerEvent();
+    static_cast<CKeyPublisher*>(aThis)->HandleTimerEvent();
+    return 0;
+    
+    }
+
+// -----------------------------------------------------------------------
+// CKeyPublisher::Redraw   (part of CWindowAnim - pure virtual function) 
+// Description: 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::Redraw()
+    {
+    //Pass
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::FocusChanged   (part of CWindowAnim - pure virtual function)
+// Description: 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::FocusChanged(TBool /*aState*/)
+    {
+    //Pass
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::CommandReplyL  (part of CAnim - pure virtual function)
+// Description: 
+// -----------------------------------------------------------------------
+//
+TInt CKeyPublisher::CommandReplyL(TInt /*aOpcode*/, TAny* /*aArgs*/)
+    {
+    //Pass
+    return KErrNone;
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::Command  (part of CAnim - pure virtual function)
+// Description: 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::Command(TInt /*aOpcode*/, TAny* /*aArgs*/)
+    {
+    //Pass
+    }
+// -----------------------------------------------------------------------
+// CKeyPublisher::Animate  (part of CAnim - pure virtual function)
+// Description: 
+// -----------------------------------------------------------------------
+//
+void CKeyPublisher::Animate(TDateTime* /*aDateTime*/)
+    {
+    //Pass
+    }
+
+// End of File