uifw/AvKon/src/AknEcs.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 21 558113899881
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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:   Support for Emergency Calls. Class Implementations.
       
    15 *   Pressed keys are tracked in a buffer and CEmergencyNumberUtils
       
    16 *   is used to find out if the buffer matches to emergency number.
       
    17 *   Observers, if registered are called to notify them.
       
    18 *
       
    19 *
       
    20 */
       
    21 
       
    22 
       
    23 
       
    24 // INCLUDES
       
    25 #include <e32std.h>
       
    26 #include "aknenv.h"
       
    27 #include "aknappui.h"
       
    28 #include "AknEcs.h"
       
    29 #include <featmgr.h>
       
    30 #include "AknDebug.h"
       
    31 
       
    32 #include <CPhCltEmergencyCall.h>
       
    33 #include <MPhCltEmergencyCallObserver.h>
       
    34 #include <PhCltTypes.h>
       
    35 #include <AvkonInternalCRKeys.h>
       
    36 #include <PtiDefs.h>
       
    37 #include <e32property.h>
       
    38 
       
    39 
       
    40 // CLASS DECLARATIONS
       
    41 
       
    42 /** Class for getting emergency call events */
       
    43 NONSHARABLE_CLASS(CPhCltEmergencyCallObserver) : public CBase,
       
    44                                                  public MPhCltEmergencyCallObserver
       
    45     {
       
    46     public:
       
    47         /** Constructor */
       
    48         CPhCltEmergencyCallObserver(CAknEcsDetector* aParent);
       
    49         
       
    50         /** Destructor */
       
    51         ~CPhCltEmergencyCallObserver( );
       
    52         
       
    53        /**
       
    54          * This method is called when client's dial request is completed.
       
    55          *
       
    56          * @param aStatus error code of the success of the operation.
       
    57          */       
       
    58         virtual void HandleEmergencyDialL( const TInt aStatus );
       
    59     private:
       
    60         /** Pointer to the parent object that really handles the events. */
       
    61         CAknEcsDetector* iParent;
       
    62     };
       
    63     
       
    64     
       
    65 CPhCltEmergencyCallObserver::CPhCltEmergencyCallObserver(CAknEcsDetector* aParent)
       
    66     :iParent(aParent)
       
    67     {
       
    68     }
       
    69     
       
    70 CPhCltEmergencyCallObserver::~CPhCltEmergencyCallObserver()
       
    71     {
       
    72     }
       
    73     
       
    74 void CPhCltEmergencyCallObserver::HandleEmergencyDialL( const TInt /*aStatus*/ )
       
    75     {
       
    76 #ifdef AVKON_RDEBUG_INFO
       
    77     _LIT(KDebugDialRequestCompleted, "Dial request is completed");
       
    78     RDebug::Print(KDebugDialRequestCompleted);
       
    79 #endif
       
    80     iParent->CallAttemptedCallback( iParent );    
       
    81     }
       
    82        
       
    83 /**
       
    84 * Class to hold the queue of keys (TText characters) provided to the emergency call detector.
       
    85 *
       
    86 * Performs matching of an emergency number with the current queue.
       
    87 *
       
    88 * No memory is allocated after its complete construction
       
    89 *
       
    90 */
       
    91 NONSHARABLE_CLASS(CAknMatchingCharacterQueue) : public CBase
       
    92     {
       
    93     public:
       
    94         /**
       
    95         * These statuses are returned by MatchText
       
    96         */
       
    97         enum TStatus
       
    98             {
       
    99             ENoMatch,
       
   100             ECompleteMatch
       
   101             };
       
   102     public:
       
   103         /**
       
   104         * C++ constructor
       
   105         */
       
   106         CAknMatchingCharacterQueue( CPhCltEmergencyCall* aPhCltEmergencyCall );
       
   107 
       
   108         /**
       
   109         * C++ destructor
       
   110         */
       
   111         ~CAknMatchingCharacterQueue( );
       
   112 
       
   113         /**
       
   114         * 2nd phase constructor
       
   115         */
       
   116         void ConstructL();
       
   117 
       
   118         /**
       
   119         * Method to reset the buffer by resetting the pointers.
       
   120         *
       
   121         */
       
   122         void Reset();
       
   123 
       
   124         /**
       
   125         * Adds the passed character code to the queue. All codes append to the queue;
       
   126         * none are ignored.
       
   127         *
       
   128         * @param aNewChar New char to the queue.
       
   129         */
       
   130         void AddChar( TText aNewChar );
       
   131 
       
   132 
       
   133         /**
       
   134         * Set the entire contents of the queue. If the new buffer is longer than
       
   135         * the queue, rest are stripped.
       
   136         *
       
   137         * @param aNewBuffer New content to the queue.
       
   138         */
       
   139         void SetBuffer( const TDesC& aNewBuffer );
       
   140 
       
   141         /**
       
   142         * The number of characters in the queue.  Resets to 0. Increases as characters are added
       
   143         * up to and equal to KAknEcsMaxMatchingLength
       
   144         *
       
   145         * @return   the number of characters queued and available for match.
       
   146         *
       
   147         */
       
   148         TInt Count() const;
       
   149 
       
   150         /**
       
   151         * Returns the status of the queue (which is automatically updated when AddChar and other non-const
       
   152         * API is called)
       
   153         * @return The status of the match. Nothing matching returns ENoMatch; 
       
   154         *         The whole sequence matching returns ECompleteMatch.
       
   155         */
       
   156         TStatus Status() const;
       
   157 
       
   158         /**
       
   159         * Returns a pointer to the current matching number. 
       
   160         *
       
   161         * @return A ptr descriptor into the currently matching text
       
   162         */
       
   163         TPtrC CurrentMatch() const;
       
   164 
       
   165         /**
       
   166         * Returns an index to the current character buffer where the emergency number
       
   167         * match begins.  This value is between 0 and KAknEcsMaxMatchingLength, even if
       
   168         * there have been a large number characters input to the FIFO. Thus, it does not
       
   169         * take account of characters that have fallen out of the FIFO.
       
   170         *
       
   171         * @return the index in the current buffer where the match starts
       
   172         */
       
   173         TInt IndexOfCurrentMatch() const;
       
   174 
       
   175     private:
       
   176         /**
       
   177         * Update the status of the queue
       
   178         */
       
   179         void UpdateStatus( TBool aBufferMode );
       
   180 
       
   181     private:
       
   182         // Emergency number buffer is as long as maximum sequence
       
   183         TBuf<KAknEcsMaxMatchingLength> iCharBuffer;
       
   184 
       
   185         /** Pointer to phone client interface of emergency call. Not owned */
       
   186         CPhCltEmergencyCall* iPhCltEmergencyCall; 
       
   187         TStatus iStatus;      // Holds the status;
       
   188         TInt iMatchPosition;  // Position in iCharBuffer from where the match starts.
       
   189 
       
   190         TAny* iSpare;
       
   191     };
       
   192 
       
   193 
       
   194 
       
   195 
       
   196 // CLASS IMPLEMENTATIONS
       
   197 
       
   198 /**
       
   199  * Local Panic Function and Panic Codes
       
   200  */
       
   201 
       
   202 enum TAknEcsPanicCodes
       
   203     {
       
   204     EAknEcsPanicDialLLeft = 1,
       
   205     EAknEcsPanicBadState
       
   206     };
       
   207 
       
   208 GLDEF_C void Panic(TAknEcsPanicCodes aPanic)
       
   209     {
       
   210     _LIT(KPanicCat,"AknEcs");
       
   211     User::Panic(KPanicCat, aPanic);
       
   212     }
       
   213 
       
   214 //
       
   215 // Queue used for storing and matching the keys used in emergency number detection
       
   216 //
       
   217 //
       
   218 
       
   219 
       
   220 CAknMatchingCharacterQueue::CAknMatchingCharacterQueue( CPhCltEmergencyCall* aPhCltEmergencyCall ) 
       
   221         : iPhCltEmergencyCall( aPhCltEmergencyCall )
       
   222     {
       
   223     Reset();
       
   224     }
       
   225 
       
   226 CAknMatchingCharacterQueue::~CAknMatchingCharacterQueue( )
       
   227     {
       
   228     }
       
   229 
       
   230 void CAknMatchingCharacterQueue::ConstructL()
       
   231     {
       
   232     }
       
   233 
       
   234 void CAknMatchingCharacterQueue::Reset()
       
   235     {
       
   236     iMatchPosition = 0;
       
   237     iCharBuffer.Zero();
       
   238     }
       
   239 
       
   240 void CAknMatchingCharacterQueue::AddChar( TText aNewChar )
       
   241     {    
       
   242     TInt length = iCharBuffer.Length();
       
   243     TInt maxLenght = iCharBuffer.MaxLength();
       
   244     if (length >= maxLenght)
       
   245         {
       
   246         iCharBuffer = iCharBuffer.Right(length - 1);
       
   247         }
       
   248     iCharBuffer.Append( aNewChar );
       
   249     UpdateStatus( EFalse );
       
   250     }
       
   251 
       
   252 void CAknMatchingCharacterQueue::SetBuffer( const TDesC& aNewBuffer )
       
   253     {    
       
   254     TInt maxLenght = iCharBuffer.MaxLength();
       
   255     TInt length = aNewBuffer.Length();
       
   256     if ( length > maxLenght )
       
   257         {
       
   258         length = maxLenght;
       
   259         }
       
   260     iCharBuffer = aNewBuffer.Left( length );
       
   261     UpdateStatus( ETrue );
       
   262     }
       
   263 
       
   264 TInt CAknMatchingCharacterQueue::Count() const
       
   265     {
       
   266     return iCharBuffer.Length();
       
   267     }
       
   268 
       
   269 CAknMatchingCharacterQueue::TStatus CAknMatchingCharacterQueue::Status() const
       
   270     {
       
   271     return iStatus;
       
   272     }
       
   273 
       
   274 TPtrC CAknMatchingCharacterQueue::CurrentMatch() const
       
   275     {
       
   276     return TPtrC(iCharBuffer.Right(iCharBuffer.Length() - iMatchPosition));
       
   277     }
       
   278 
       
   279 TInt CAknMatchingCharacterQueue::IndexOfCurrentMatch() const
       
   280     {
       
   281     return iMatchPosition;
       
   282     }
       
   283 
       
   284 void CAknMatchingCharacterQueue::UpdateStatus( TBool aBufferMode )
       
   285     {
       
   286     TBool isEmergency = EFalse;
       
   287     TInt err = KErrNone;
       
   288     TPhCltTelephoneNumber buffer = iCharBuffer;
       
   289     if (iPhCltEmergencyCall)
       
   290         {
       
   291         err = iPhCltEmergencyCall->FindEmergencyPhoneNumber(buffer, isEmergency);        
       
   292         }
       
   293     if ( err != KErrNone )
       
   294         {
       
   295         isEmergency = EFalse;
       
   296         }
       
   297 
       
   298     TInt cbLength = iCharBuffer.Length();
       
   299     TInt bLength = buffer.Length();
       
   300 
       
   301     if ( aBufferMode && isEmergency && ( cbLength != bLength ) )
       
   302         {
       
   303         isEmergency = EFalse;
       
   304         }
       
   305 
       
   306     if ( isEmergency )
       
   307         {
       
   308         iMatchPosition = cbLength - bLength;
       
   309         iStatus = ECompleteMatch;
       
   310         }
       
   311     else
       
   312         {
       
   313         iMatchPosition = cbLength;
       
   314         iStatus = ENoMatch;
       
   315         }
       
   316     }
       
   317 
       
   318 
       
   319 //
       
   320 //
       
   321 // Implementation of CAknEcsDetector
       
   322 //  (Emergency Call Support Detector)
       
   323 //
       
   324 //
       
   325 
       
   326 EXPORT_C CAknEcsDetector::CAknEcsDetector()
       
   327     {
       
   328     iCoeEnv = CCoeEnv::Static();
       
   329     iState = ENotFullyConstructed;
       
   330     }
       
   331 
       
   332 EXPORT_C CAknEcsDetector::~CAknEcsDetector()
       
   333     {
       
   334     // Must close this in order to remove any observers from the AppUi's monitor
       
   335     CloseEventSource();
       
   336     delete iPhCltEmergencyCall;
       
   337     delete iEmergencyCallObserver;
       
   338     delete iQueue;
       
   339     delete iIdler;
       
   340     delete iKeyTimeoutTimer;
       
   341     }
       
   342 
       
   343 EXPORT_C void CAknEcsDetector::ConstructL()
       
   344     {
       
   345     iEmergencyCallObserver = new (ELeave) CPhCltEmergencyCallObserver( this );
       
   346     // Phone client interface
       
   347     iPhCltEmergencyCall = CPhCltEmergencyCall::NewL( iEmergencyCallObserver );
       
   348     iQueue = new (ELeave) CAknMatchingCharacterQueue(iPhCltEmergencyCall);
       
   349     iQueue->ConstructL();
       
   350 
       
   351     DetermineState();
       
   352 
       
   353     // Idler for delaying the change of state to Call Attempted
       
   354     iIdler = CIdle::NewL( CActive::EPriorityLow );
       
   355 
       
   356     // Timer for timing the timeout between keys
       
   357     iKeyTimeoutTimer = CPeriodic::NewL( CActive::EPriorityLow);
       
   358     }
       
   359 
       
   360 EXPORT_C CAknEcsDetector* CAknEcsDetector::NewL()
       
   361     { // static
       
   362     CAknEcsDetector* self = new (ELeave) CAknEcsDetector();
       
   363     CleanupStack::PushL( self );
       
   364     self->ConstructL();
       
   365     CleanupStack::Pop(); //self
       
   366     return self;
       
   367     }
       
   368 
       
   369 EXPORT_C TBool CAknEcsDetector::ConnectToEventSource()
       
   370     {
       
   371     if ( iFlags.IsClear( EEventSourceConnected ) )
       
   372         {
       
   373         TRAPD( err, iAvkonAppUi->EventMonitor()->AddObserverL(this) );
       
   374         iFlags.Assign( EEventSourceConnected, ( err == KErrNone ) );
       
   375         return ( err == KErrNone );
       
   376         }
       
   377     else
       
   378         {
       
   379         return ETrue;
       
   380         }
       
   381     }
       
   382 
       
   383 EXPORT_C void CAknEcsDetector::CloseEventSource()
       
   384     {
       
   385     if (iFlags.IsSet( EEventSourceConnected ) )
       
   386         {
       
   387         CAknWsEventMonitor* eventMonitor = iAvkonAppUi->EventMonitor();
       
   388         eventMonitor->RemoveObserver(this);
       
   389         iFlags.Clear( EEventSourceConnected );
       
   390         }
       
   391     }
       
   392 
       
   393 EXPORT_C void CAknEcsDetector::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* /* aDestination  */)
       
   394     {
       
   395     if ( aEvent.Type() == EEventKeyDown || 
       
   396     // EKeyPhoneEnd/EKeyNo doesn't send EEVentKeyDown events, so EEventKey is used instead
       
   397     ( ( aEvent.Key()->iScanCode == EStdKeyNo ) && ( aEvent.Type() == EEventKey ) ) 
       
   398         )
       
   399         {
       
   400         AddChar( (TText)(aEvent.Key()->iScanCode ) ); // top 16 ( in Unicode build) bits removed
       
   401         }    
       
   402     }
       
   403 
       
   404 
       
   405 EXPORT_C void CAknEcsDetector::AddChar( TText aNewChar )
       
   406     {
       
   407     iKeyTimeoutTimer->Cancel(); // there might be pending timeout; clear it
       
   408     if ( aNewChar == EStdKeyYes || aNewChar ==EKeyPhoneSend )
       
   409         {
       
   410         if ( State() == ECompleteMatch )
       
   411             {
       
   412             SetState( ECompleteMatchThenSendKey );
       
   413             }
       
   414         // else do nothing with it...
       
   415         }
       
   416     else
       
   417         {
       
   418         TText scanCode = aNewChar;
       
   419 #ifdef RD_INTELLIGENT_TEXT_INPUT 
       
   420         // Convert scan code to number value here 
       
   421         // for 4*10, 3*11, half-qwerty key pad
       
   422         // The convert value is referenced from KeymapBuilder.pl in ptienginev2
       
   423         // Note: if the product change the scancode defintion,pls change the following 
       
   424         // map rules.
       
   425         TInt keyboardLayout = EPtiKeyboardNone;
       
   426         TInt errCode = RProperty::Get( KCRUidAvkon, KAknKeyBoardLayout, keyboardLayout );
       
   427         if ( errCode == KErrNone &&  ( keyboardLayout == EPtiKeyboardQwerty4x10 
       
   428             || keyboardLayout == EPtiKeyboardQwerty3x11 ) )
       
   429             {
       
   430             // using same conventor rule for 3x11 & 4x10
       
   431             if ( scanCode == EPtiKeyQwertyQ )
       
   432                 {
       
   433                 scanCode = EPtiKeyQwerty1;
       
   434                 }
       
   435             else if ( scanCode == EPtiKeyQwertyW )
       
   436                 {
       
   437                 scanCode = EPtiKeyQwerty2;
       
   438                 }
       
   439             else if ( scanCode == EPtiKeyQwertyE )
       
   440                 {
       
   441                 scanCode = EPtiKeyQwerty3;
       
   442                 }        
       
   443             else if ( scanCode == EPtiKeyQwertyR )
       
   444                 {
       
   445                 scanCode = EPtiKeyQwerty4;
       
   446                 }
       
   447             else if ( scanCode == EPtiKeyQwertyT )
       
   448                 {
       
   449                 scanCode = EPtiKeyQwerty5;
       
   450                 }
       
   451             else if ( scanCode == EPtiKeyQwertyY )
       
   452                 {
       
   453                 scanCode = EPtiKeyQwerty6;
       
   454                 }
       
   455             else if ( scanCode == EPtiKeyQwertyU )
       
   456                 {
       
   457                 scanCode = EPtiKeyQwerty7;
       
   458                 }
       
   459             else if ( scanCode == EPtiKeyQwertyI )
       
   460                 {
       
   461                 scanCode = EPtiKeyQwerty8;
       
   462                 }
       
   463             else if ( scanCode == EPtiKeyQwertyO )
       
   464                 {
       
   465                 scanCode = EPtiKeyQwerty9;
       
   466                 }
       
   467             else if ( scanCode == EPtiKeyQwertyP )
       
   468                 {
       
   469                 scanCode = EPtiKeyQwerty0;
       
   470                 }    
       
   471             }
       
   472         else if ( errCode == KErrNone && keyboardLayout == EPtiKeyboardHalfQwerty )
       
   473             {
       
   474             if ( scanCode == EPtiKeyQwertyE )
       
   475                 {
       
   476                 scanCode = EPtiKeyQwerty1;
       
   477                 }
       
   478             else if ( scanCode == EPtiKeyQwertyT )
       
   479                 {
       
   480                 scanCode = EPtiKeyQwerty2;
       
   481                 }
       
   482             else if ( scanCode == EPtiKeyQwertyU )
       
   483                 {
       
   484                 scanCode = EPtiKeyQwerty3;
       
   485                 }        
       
   486             else if ( scanCode == EPtiKeyQwertyD )
       
   487                 {
       
   488                 scanCode = EPtiKeyQwerty4;
       
   489                 }
       
   490             else if ( scanCode == EPtiKeyQwertyG )
       
   491                 {
       
   492                 scanCode = EPtiKeyQwerty5;
       
   493                 }
       
   494             else if ( scanCode == EPtiKeyQwertyJ )
       
   495                 {
       
   496                 scanCode = EPtiKeyQwerty6;
       
   497                 }
       
   498             else if ( scanCode == EPtiKeyQwertyU )
       
   499                 {
       
   500                 scanCode = EPtiKeyQwertyC;
       
   501                 }
       
   502             else if ( scanCode == EPtiKeyQwertyB )
       
   503                 {
       
   504                 scanCode = EPtiKeyQwerty8;
       
   505                 }
       
   506             else if ( scanCode == EPtiKeyQwertyM )
       
   507                 {
       
   508                 scanCode = EPtiKeyQwerty9;
       
   509                 }
       
   510             else if ( scanCode == EPtiKeyQwertySpace )
       
   511                 {
       
   512                 scanCode = EPtiKeyQwerty0;
       
   513                 }    
       
   514             }
       
   515 #endif   //RD_INTELLIGENT_TEXT_INPUT    
       
   516         
       
   517         iQueue->AddChar( scanCode );
       
   518         DetermineState();
       
   519         iKeyTimeoutTimer->Start( KEcsInterKeyTimeout, KEcsInterKeyTimeout, TCallBack( CancelMatch, this ) );
       
   520         }
       
   521     }
       
   522 
       
   523 
       
   524 void CAknEcsDetector::DetermineState()
       
   525     {
       
   526     TState bestState = ENoMatch;
       
   527 
       
   528     if ( iQueue->Count() == 0 )
       
   529         {
       
   530         bestState = EEmpty;
       
   531         }
       
   532     else
       
   533         {
       
   534         CAknMatchingCharacterQueue::TStatus matchStatus = iQueue->Status();
       
   535 
       
   536         switch ( matchStatus )
       
   537             {
       
   538             case CAknMatchingCharacterQueue::ENoMatch:
       
   539                 bestState = ENoMatch;
       
   540                 break;
       
   541             case CAknMatchingCharacterQueue::ECompleteMatch:
       
   542                 bestState = ECompleteMatch;
       
   543                 break;
       
   544             default:
       
   545                 __ASSERT_DEBUG( 0, Panic(EAknEcsPanicBadState) );
       
   546                 break;
       
   547             }
       
   548         SetState(bestState);
       
   549         }
       
   550     }
       
   551 
       
   552 EXPORT_C void CAknEcsDetector::ReportEvent(TState aNewState )
       
   553     {
       
   554     if (iObserver)
       
   555         {
       
   556         iObserver->HandleEcsEvent( this, aNewState );
       
   557         }
       
   558     }
       
   559 
       
   560 
       
   561 EXPORT_C TPtrC CAknEcsDetector::CurrentMatch() const
       
   562     {
       
   563     return iQueue->CurrentMatch();
       
   564     }
       
   565 
       
   566 TInt CAknEcsDetector::IndexOfCurrentMatch() const
       
   567     {
       
   568     return iQueue->IndexOfCurrentMatch();
       
   569     }
       
   570 
       
   571 EXPORT_C CAknEcsDetector::TState CAknEcsDetector::State()
       
   572     {
       
   573     return iState;
       
   574     }
       
   575 EXPORT_C void CAknEcsDetector::SetBuffer( const TDesC& aNewBuffer )
       
   576     {
       
   577     iKeyTimeoutTimer->Cancel(); // there might be pending timeout; clear it
       
   578     iQueue->Reset();
       
   579     iQueue->SetBuffer(aNewBuffer);
       
   580     DetermineState();
       
   581     if ( State() == ECompleteMatch )
       
   582         {
       
   583         iKeyTimeoutTimer->Start( KEcsInterKeyTimeout,
       
   584             KEcsInterKeyTimeout, TCallBack( CancelMatch, this ) );
       
   585         }
       
   586     }
       
   587 
       
   588 EXPORT_C void CAknEcsDetector::SetState( TState aNewState )
       
   589     {
       
   590     ReportEvent( aNewState );
       
   591 
       
   592     TInt oldState = iState;
       
   593     iState = aNewState;
       
   594 
       
   595     switch ( oldState )
       
   596         {
       
   597         // All these are OK to go to the next state without transition action:
       
   598         case ENotFullyConstructed:
       
   599         case EEmpty:
       
   600         case ECallAttempted:
       
   601         case ENoMatch:
       
   602         case ECompleteMatchThenSendKey:
       
   603             break;
       
   604 
       
   605         case ECompleteMatch:
       
   606             if ( aNewState == ECompleteMatchThenSendKey )
       
   607                 {
       
   608                 RelinquishCapturedKeys();
       
   609 
       
   610                 TBool proceedWithCall = ETrue;
       
   611                 proceedWithCall = OfferEmergencyCall();
       
   612                 if ( proceedWithCall )
       
   613                     {
       
   614                     AttemptEmergencyCall();
       
   615                     }
       
   616                 else
       
   617                     {  // Pass through this state immediately
       
   618                     iQueue->Reset();
       
   619                     SetState( EEmpty );
       
   620                     }
       
   621                 }
       
   622             break;
       
   623 
       
   624         default:
       
   625             break;
       
   626 
       
   627         }
       
   628     }
       
   629 
       
   630 EXPORT_C void CAknEcsDetector::Reset()
       
   631     {
       
   632     iQueue->Reset();
       
   633     SetState( EEmpty );
       
   634     }
       
   635 
       
   636 /**
       
   637 * This may be re-implemented to add a confirm query. Re-implementation must not leave
       
   638 *
       
   639 */
       
   640 EXPORT_C TBool CAknEcsDetector::OfferEmergencyCall()
       
   641     {
       
   642     return ETrue;
       
   643     }
       
   644 
       
   645 void CAknEcsDetector::CaptureKeys()
       
   646     {
       
   647     // Capture Send Key
       
   648     RWindowGroup& groupWin=iCoeEnv->RootWin();
       
   649     iCapturedKey=groupWin.CaptureKey( EStdKeyYes, 0, 0);
       
   650     }
       
   651 
       
   652 void CAknEcsDetector::RelinquishCapturedKeys()
       
   653     {
       
   654     RWindowGroup& groupWin=iCoeEnv->RootWin();
       
   655     groupWin.CancelCaptureKey( iCapturedKey );
       
   656     }
       
   657 
       
   658 void CAknEcsDetector::AttemptEmergencyCall()
       
   659     {
       
   660 #ifdef AVKON_RDEBUG_INFO
       
   661     _LIT(KDebugAttemptEmergencyCall, "Attempt Emergency Call From Detector");
       
   662     RDebug::Print(KDebugAttemptEmergencyCall);
       
   663 #endif
       
   664 
       
   665     TRAPD( err, iPhCltEmergencyCall->DialEmergencyCallL( CurrentMatch() ) );
       
   666     __ASSERT_DEBUG( err==KErrNone, Panic( EAknEcsPanicDialLLeft ) );
       
   667     if(err != KErrNone)
       
   668         {
       
   669         err = KErrNone;
       
   670         }
       
   671     }
       
   672 
       
   673 EXPORT_C void CAknEcsDetector::SetObserver( MAknEcsObserver* aObserver )
       
   674     {
       
   675     iObserver = aObserver;
       
   676     }
       
   677 
       
   678     /**
       
   679      * It is called whenever status is retrieved (by the client).
       
   680      *
       
   681      * @param aStatus It is the status of the phone.
       
   682      */
       
   683 void CAknEcsDetector::HandlePhoneStatusL( const TInt /* aStatus */ )
       
   684     {
       
   685     }
       
   686 
       
   687     /**
       
   688     * This is meant to be called asynchronously in order for the Observer to destroy itself
       
   689     *
       
   690     */
       
   691 TInt CAknEcsDetector::CallAttemptedCallback(TAny* aSelf)
       
   692     { // static
       
   693     REINTERPRET_CAST(CAknEcsDetector*,aSelf)->SetState( ECallAttempted );
       
   694 #ifdef AVKON_RDEBUG_INFO
       
   695     _LIT(KDebugCallAttemptedCallback, "CallAttemptedCallback");
       
   696     RDebug::Print(KDebugCallAttemptedCallback);
       
   697 #endif
       
   698     return 0;
       
   699     }
       
   700 
       
   701 TInt CAknEcsDetector::CancelMatch(TAny* aThis)
       
   702     {
       
   703     static_cast<CAknEcsDetector*>(aThis)->Reset();
       
   704     static_cast<CAknEcsDetector*>(aThis)->iKeyTimeoutTimer->Cancel();
       
   705     return 0; // Do not repeat the operation
       
   706     }
       
   707 
       
   708 // End of File