alarmui/src/AlmAlarmControl.cpp
author Simon Howkins <simonh@symbian.org>
Mon, 22 Nov 2010 16:01:09 +0000
branchRCL_3
changeset 93 d216ae5a8733
parent 86 ed599363c2d7
permissions -rw-r--r--
Adjusted to avoid exports, etc, from a top-level bld.inf

/*
* Copyright (c) 2006-2006 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:   An alarm UI class, CAlmAlarmControl.
*                This class takes care of displaying the alarm note and
*                handling user input.
*
*/



// INCLUDE FILES
#include "AlmAlarmControl.h"
#include "pim_trace.h"
#include "alarmutils.h"
#include <secondarydisplay/alarmuiSecondaryDisplay.h>
#include <bautils.h>
#include <StringLoader.h>
#include <pathinfo.h>
#include <featmgr.h>
#include <aknnotewrappers.h>
#include <coreapplicationuisdomainpskeys.h>
#include <alarmuidomainpskeys.h>
#include <data_caging_path_literals.hrh>

#include <AlmAlert.rsg>
#include "AlmAlert.hrh"
#include "AlmAlert.pan"

#include <aknnotewrappers.h>
#include <AknMediatorFacade.h>

#include <missedalarm.h>

_LIT( KResourceFile, "AlmAlert.rsc" );

const TInt KAlarmPriority( 3095 );  // Priority for global note queue

const TUint KAlarmAutoShutdown( 60000000 );  // 60 s
const TUint KShutdownTime( 1500000 ); // 1.5 s

const TInt KErrDuplicateAlarm( -1001 ); // error code


// ==========================================================
// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
//
void CAlmAlarmControl::Panic(const TUint aReason) const
{
    TRACE_ENTRY_POINT;
    _LIT( KPanicCategory, "AlarmUI-AlmAlert.pan" );
    User::Panic( KPanicCategory, aReason );
    TRACE_EXIT_POINT;
}

// -----------------------------------------------------------------------------
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CAlmAlarmControl::CAlmAlarmControl() :
    iGlobalNoteId( KErrNotFound ),
    iState( EStateIdle )
{
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
}

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
//
CAlmAlarmControl::~CAlmAlarmControl()
{
    TRACE_ENTRY_POINT;
    this->HideAlarm();

    delete iAlarmUtils;
    iAlarmUtils = NULL;

    iEikonEnv->EikAppUi()->RemoveFromStack( this );
    iEikonEnv->DeleteResourceFile( iResOffset );

    delete iPropertyHideAlarm;
    iPropertyHideAlarm = NULL;

    delete iPropertySWStateValue;
    iPropertySWStateValue = NULL;

    delete iPropertyStopAlarm;
    iPropertyStopAlarm = NULL;

    delete iPropertySnoozeAlarm;
    iPropertySnoozeAlarm = NULL;
    TRACE_EXIT_POINT;
}

// --------------------------------------------------------
//
// ---------------------------------------------------------
//
void CAlmAlarmControl::SetState(TInt aState)
{
    TRACE_ENTRY_POINT;
    const TInt oldState( iState );
    iState = aState;
    // handle state transitions
    HandleStateChange( oldState );
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// handle custom state transitions
// ---------------------------------------------------------
//
void CAlmAlarmControl::HandleStateChange(TInt aOldState)
{
    TRACE_ENTRY_POINT;

    // stop observers when exiting from EStateWaitingInput state
    if( aOldState == EStateWaitingInput
        && iState != EStateWaitingInput )
    {
        // stop the context/sensor observer.
        PIM_TRAPD_ASSERT( iAlarmUtils->StopCFObserverL(); )

        // stop waiting for "end call" command from accessories
        iAlarmUtils->StopAccessoryObserver();
    }

    switch( iState )
    {
        case EStateIdle:
        {
            iAlarmUtils->StopInactivityResetTimer();

            // was the device started for alarm?
            if( iAlarmUtils->IsDeviceInAlarmState() )
            {
                /**
                * Show the wakeup query if any of the alarms was stopped (by user
                * pressing the stop key) and there is no more alarms in the queue.
                */
                if( iAskWakeup && !iAlarmUtils->HasExpiredAlarmsWaiting() )
                {
                    SetState( EStateBeforeAskingWakeup );
                    iAlarmUtils->AsyncShowWakeupQuery();
                }
                else
                {
                    /**
                    * Prepare to shutdown if wakeup query is not needed.
                    * (also works as a fallback if we are waiting for more
                    * alarms to be notified (iAlarmUtils->HasExpiredAlarmsWaiting()==ETrue),
                    * but alarm server queue changes suddenly)
                    */
                    iAlarmUtils->StartShutdownTimer( KShutdownTime );
                }
            }
            else
            {
                /**
                * block all input for 0.5 seconds
                * (try to prevent accidental key presses from going through the key or security lock)
                */
                iAlarmUtils->StartKeyBlocker();

                // reset the key guard
                iAlarmUtils->SetKeyGuard( ETrue );
            }

            break;
        }

        case EStateWaitingInput:
        {
            // make sure the screen saver, key or security lock, etc. won't active during the alarm
            iAlarmUtils->StartInactivityResetTimer();

            // start waiting for "end call" command from accessories
            iAlarmUtils->StartAccessoryObserver();

            // publish new alarm context value and wait for any actions
            PIM_TRAPD_ASSERT( iAlarmUtils->StartCFObserverL(); )
            break;
        }

        default:
            // fall through
            break;
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
TBool CAlmAlarmControl::IsState(const TInt aState) const
{
    TRACE_ENTRY_POINT;
    TBool retVal(iState == aState);
    TRACE_EXIT_POINT;
    return retVal;
}

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
void CAlmAlarmControl::DoAutoSnooze()
    {
    TRACE_ENTRY_POINT;
    iAlarmUtils->CancelAutoSnooze();

    // Allow auto-snooze only while waiting user input
    if( IsState( EStateWaitingInput ) )
        {
        SetState( EStateAfterInput );
	 StopOrSnoozeAlarm();
	 DoCancelDialog();
        }
    TRACE_EXIT_POINT;
    }

// ---------------------------------------------------------
// Dismiss the alarm notification.
// ---------------------------------------------------------
//
void CAlmAlarmControl::DoCancelDialog()
{
    TRACE_ENTRY_POINT;
    if( iGlobalNoteId != KErrNotFound )
    {
        iAlarmUtils->NotifierDialogController()->SetNoteObserver( this );
        iAlarmUtils->NotifierDialogController()->CancelNote( iGlobalNoteId );
    }
    iAlarmUtils->StopAlarmSound();
    iAlarmUtils->CancelAutoSnooze();
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// Show the wake-up query
// ---------------------------------------------------------
//
void CAlmAlarmControl::AskWakeupPhoneL()
{
    TRACE_ENTRY_POINT;
    iAskWakeup = EFalse;
    ASSERT( IsState( EStateBeforeAskingWakeup ) );
    if( IsState( EStateBeforeAskingWakeup ) )
    {
        HBufC* label = NULL;
        TBuf<1> time;
        iAlarmUtils->GetWakeupLabelL( label );
        CleanupStack::PushL( label );

		if(!IsVisible())
		{
			MakeVisible(ETrue);
		}
        iAlarmUtils->NotifierDialogController()->SetNoteObserver( this );
        iGlobalNoteId = iAlarmUtils->NotifierDialogController()->DisplayAlarmL( EAskWakeUp, *label, time/*not used*/ );

        CleanupStack::PopAndDestroy( label );

        // shutdown automatically if user doesn't react within one minute
        iAlarmUtils->StartShutdownTimer( KAlarmAutoShutdown );
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// Handle alarm interrupt commands (power key)
// ---------------------------------------------------------
//
void CAlmAlarmControl::HandleInterruptAlarm(TInt aReason)
{
    TRACE_ENTRY_POINT;
    switch( aReason )
    {
        case EReasonKSysApHideAlarm:  // stop
        {
            switch( iState )
            {
                case EStateIdle:
                {
                    // ignore
                }
                break;

                case EStateWaitingShowRequest:  // stop -> EStateIdle
                case EStateWaitingDisplayRequest:  // stop -> hide -> EStateIdle
                case EStateWaitingInput:  // stop -> hide -> EStateIdle
                {
                    iAskWakeup = EFalse; // don't show the wakeup query!
                    SetState( EStateIdle );
                    // Stop alarm -> HideAlarm() -> CancelNote()
                    iAlarmUtils->DoStopAlarm();  // stop
                    DoCancelDialog();
                }
                break;

                case EStateBeforeAskingWakeup:  // hide and shutdown
                case EStateAskingWakeup:  // hide and shutdown
                {
                    iAskWakeup = EFalse;
                    iAlarmUtils->CancelAsynchRequest();
                    SetState( EStateIdle );
                    DoCancelDialog();
                }
                break;

                case EStateAfterInput:
                case EStateShowingSnoozeInfo:
                {
                    SetState( EStateIdle );
                }
                break;

                default:
                {
                    // panic - unknown state!
                    Panic( EAlarmUIUnknownState | EAlarmUIHandleInterrupt );
                }
                break;
            }
            break;
        }

        default:
        {
            // Unknown reason
            Panic( EAlarmUIUnknownReason | EAlarmUIHandleInterrupt );
        }
        break;
    }
    TRACE_EXIT_POINT;
}


// ---------------------------------------------------------
// Stores the missed alarm data in the repository  
// ---------------------------------------------------------
//
void CAlmAlarmControl::StoreMissedAlarmDataL()
    {
	//Get the Calendar instance values and         	  
	//Store it in the missed alarm repository
	
	RPointerArray<CMissedAlarm> missedAlarmList;
	TCalLocalUid localUid = iAlarmUtils->AlarmData().iLocalUid;
	TCalTime instanceTime = iAlarmUtils->AlarmData().iInstanceTime;
	TTime startTime = instanceTime.TimeLocalL();
	CMissedAlarm* missedAlarm = CMissedAlarm::NewL( localUid, startTime,
	                                                     iAlarmUtils->AlarmData().iCalFileName );
	CleanupStack::PushL( missedAlarm );
	missedAlarmList.AppendL(missedAlarm);

	CMissedAlarmStore* missedAlarmStore = CMissedAlarmStore::NewLC();
	missedAlarmStore->AddL(missedAlarmList);
		
	CleanupStack::PopAndDestroy( missedAlarmStore );
	CleanupStack::Pop( missedAlarm );
	missedAlarmList.ResetAndDestroy();
    }


// ---------------------------------------------------------
// Checks for calendar type alarm needed to be stored as missed alarm   
// Stops the alarm and enters to missed alarm table. If the calendar type
// is clock, then snoozes the alarm.
// ---------------------------------------------------------
//
void CAlmAlarmControl::StopOrSnoozeAlarm()
	{
	
	TRACE_ENTRY_POINT;
	if( iAlarmUtils->IsCalendarAlarm() )
		{	 
		if( iAlarmUtils->IsCalendarAlarmViewer() )
			{				 
			iAlarmUtils->SetCalendarAlarmViewer(EFalse);		   
			}
		else
			{
			TRAP_IGNORE( StoreMissedAlarmDataL() );
			}
		iAlarmUtils->DoStopAlarm(); 										 
		}
	else
		{		 
		iAlarmUtils->TryToSnoozeActiveAlarm();
		}
    	TRACE_EXIT_POINT;
	}

// ===========================================================
// ================ INHERITED FUNCTIONS ======================

// ---------------------------------------------------------
// Symbian 2nd phase constructor
// ---------------------------------------------------------
//
void CAlmAlarmControl::ConstructL(CAknAlarmService* aSupervisor)
{
    TRACE_ENTRY_POINT;
  
  TFileName fileName;
	// Get the complate path of the DLL from where it is currently loaded
	Dll::FileName( fileName );
	
	TFileName resFile;
	
	// Append the Drive letters ex., Z: or C:
	resFile.Append(fileName.Mid(0,2));
	resFile.Append(KDC_RESOURCE_FILES_DIR);
    resFile.Append(KResourceFile);
    
    BaflUtils::NearestLanguageFile( iEikonEnv->FsSession(), resFile );
    iResOffset = iEikonEnv->AddResourceFileL( resFile );
    

    iEikonEnv->EikAppUi()->AddToStackL(
        this,
        ECoeStackPriorityAlert,
        ECoeStackFlagRefusesFocus );

	MakeVisible(EFalse);
	SetStopFromContext(EFalse);
    iAlarmUtils = CAlarmUtils::NewL( this, aSupervisor );

    // observe "hide alarm" commands (i.e. powerkey presses)
    iPropertyHideAlarm = CPropertyObserver::NewL( *this, KPSUidCoreApplicationUIs, KCoreAppUIsHideAlarm );

    // observe system state changes
    iPropertySWStateValue = CPropertyObserver::NewL( *this, KPSUidStartup, KPSGlobalSystemState );
    //For Plasma accessory handling
    _LIT_SECURITY_POLICY_PASS( KGeneralReadPolicy );
	_LIT_SECURITY_POLICY_C1( KProtectedWritePolicy, ECapabilityWriteDeviceData );

	RProperty::Define( KPSUidAlarmExtCntl, KAlarmStopKey, RProperty::EInt, KGeneralReadPolicy, KProtectedWritePolicy );
    RProperty::Define( KPSUidAlarmExtCntl, KAlarmSnoozeKey, RProperty::EInt, KGeneralReadPolicy, KProtectedWritePolicy );

    //observe Plasma accessory stop key changes
    iPropertyStopAlarm = CPropertyObserver::NewL(*this, KPSUidAlarmExtCntl, KAlarmStopKey);

    //observe Plasma accessory snooze key changes
    iPropertySnoozeAlarm = CPropertyObserver::NewL(*this, KPSUidAlarmExtCntl, KAlarmSnoozeKey);
    //observe SysAp backlight setting PS Key
	iPropertyBacklight = CPropertyObserver::NewL(*this, KPSUidCoreApplicationUIs, KLightsAlarmLightActive);
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::Release()
{
    TRACE_ENTRY_POINT;
    delete this;
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm
// NOTE!!! This function is also called from HandlePropertyChange()
// ---------------------------------------------------------
//
void CAlmAlarmControl::ShowAlarm()
{
    TRACE_ENTRY_POINT;
    switch( iState )
    {
        case EStateWaitingShowRequest:
        {
            /**
            * wait until device startup is ready,
            * snooze info note is not being displayed and
            * delay timer has finished.
            */
            if( iAlarmUtils->IsPhoneStartupReady() &&
                !iSnoozeInfoNoteActive &&
                !iAlarmUtils->AlarmDelayTimerActive() )
            {
                // State MUST be set before requesting the note from avkon!
                // DisplayAlarmL() will call DisplayDialogL() directly!
                SetState( EStateWaitingDisplayRequest );

                // Only call this within ShowAlarm to prevent updating data too early/late.
                // (e.g. updating snooze time before showing the snooze info note)
                TRAPD( err, iAlarmUtils->InitialiseAlarmDataL(); )

                HBufC* text = NULL;

				if(!err && iAlarmUtils->CheckForDuplicateAlarm())
					{
					err = KErrDuplicateAlarm;
					}
				
                if( !err )
                {
                    TRAP( err, iAlarmUtils->GetAlarmLabelL( text ); )
                }
            	// cleanup (release global data)
            	iAlarmUtils->UninitialiseAlarmData();
                if( !err )
                {
                	if(!IsVisible())
                	{
                		MakeVisible(ETrue);
                	}
                    iAlarmUtils->NotifierDialogController()->SetNoteObserver( this );

                    // setup CBA for the global note
                    TUint cba(0);  // See AknDialogController.h
                    // alarm type - no silence key for clock alarms, unknown alarms are handled as calendar alarms
                    cba |= iAlarmUtils->IsClockAlarm() ? EClockAlarm | ENoSilence : ECalendarAlarm;
                    // disable silence key when ringing type is set to "silent" or if alarm sounds is set off
                    cba |= iAlarmUtils->IsRingingTypeSilent() || iAlarmUtils->IsOffTone() ? ENoSilence : 0;
                    // disable silence and snooze key if alarm can't be snoozed anymore
                    cba |= iAlarmUtils->CanSnooze() ? 0 : EHideSnooze | ENoSilence;
                    // show "Open" MSK for calendar alarms if the security lock is not active
                    cba |= iAlarmUtils->IsCalendarAlarm() && !iAlarmUtils->IsSecurityLockActive() ? EMskOpen : 0; 
					                  
					if(iAlarmUtils->IsCalendarAlarm())
                        {
                    	iAlarmUtils->StoreCurrentCalendarAlarmData();
						}
                    // request alarm dialog
                    TBuf<1> time;
                    TRAP( err, iGlobalNoteId = iAlarmUtils->NotifierDialogController()->DisplayAlarmL( cba, *text, time/*not used*/ ) );
                    delete text; // only delete if GetAlarmLabelL call was successfull
                    ASSERT( !err );
                }

                if( err ) // failed to fetch alarm data or show the notification
                {
                    // this happens if user has deleted calendar entry with a snoozed alarm or removed alarm from a snoozed calendar entry.
                    // (or if the DisplayAlarmL call fails)
                    // -> stop and ignore the alarm
                    HandleInterruptAlarm( EReasonKSysApHideAlarm );
                }
            }
        }
        break;

        default:
        {
            // All other states are ignored
        }
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// !!! REMEMBER !!! - This function is only called AFTER
// the alarm is snoozed or stopped
// ---------------------------------------------------------
//
void CAlmAlarmControl::HideAlarm()
{
    TRACE_ENTRY_POINT;
    switch( iState )
    {
        case EStateIdle:
        case EStateBeforeAskingWakeup:
        case EStateAskingWakeup:
        case EStateShowingSnoozeInfo:
        {
            // fall through
        }
        break;

        case EStateWaitingShowRequest:
        case EStateWaitingDisplayRequest:
        case EStateWaitingInput:
        case EStateAfterInput:
        {
            SetState( EStateIdle );
            DoCancelDialog();
        }
        break;

        default:
        {
            // panic - unknown state!
            Panic( EAlarmUIUnknownState | EAlarmUIHideAlarm );
        }
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
TInt CAlmAlarmControl::CurrentServerState() const
{
    TRACE_ENTRY_POINT;
    TRACE_EXIT_POINT;
    return iCurrentServerState;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::UpdateSoundPauseTimeInterval(TInt /*aMinutes*/)
{
    TRACE_ENTRY_POINT;
    // No implementation
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::UpdateForAlarmServerState(TInt aNewAlarmServerState)
{
    TRACE_ENTRY_POINT;
    if( iCurrentServerState != aNewAlarmServerState )
    {
        iCurrentServerState = aNewAlarmServerState;
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::UpdateAlarmInfo(const TASShdAlarm& aAlarm, const TFullName& /*aOwner*/)
{
    TRACE_ENTRY_POINT;
    // cancel timers
    iAlarmUtils->CancelAutoSnooze();
    iAlarmUtils->CancelShutdown();
    iAlarmUtils->StartAlarmDelayTimer();

    // remember to store the alarm object
    iAlarmUtils->AlarmData().iAlarm = aAlarm;

    switch( iState )
    {
        case EStateIdle:
        case EStateAfterInput:
        case EStateShowingSnoozeInfo:
        {
            /**
            * ignore and snooze other than wakeup alarms when phone is not in "normal" state
            * (special handling - don't increment the snooze count)
            */
            if( !iAlarmUtils->IsDeviceInNormalState() &&
                !iAlarmUtils->IsWakeupAlarm() )
            {
                iAlarmUtils->DoSnooze();
            }
            else
            {
                SetState( EStateWaitingShowRequest );
            }
        }
        break;

        case EStateWaitingShowRequest:
        case EStateWaitingDisplayRequest:
        case EStateWaitingInput:
        {
            // Alarm server sent the alarm back to queue...just cancel the dialog and continue.
            SetState( EStateIdle );
            DoCancelDialog();
            SetState( EStateWaitingShowRequest );
        }
        break;

        case EStateBeforeAskingWakeup:
        case EStateAskingWakeup:
        {
            /**
            * Just snooze the alarm for 1 minute (without changing the counter) and
            * let the user (or shutdown timer) handle the wakeup dialog...
            */
            iAlarmUtils->AlarmData().iSnoozeTime = 1;
            iAlarmUtils->DoSnooze();
        }
        break;

        default:
        {
            // All other states are invalid!
            Panic( EAlarmUIInvalidState | EAlarmUIUpdateAlarmInfo );
        }
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::StartPlayAlarmL(const TDesC& /*aAlarmName*/)
{
    TRACE_ENTRY_POINT;
    // No implementation.
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MEikServAlarm (MAlarmObserver)
// ---------------------------------------------------------
//
void CAlmAlarmControl::StopPlayAlarm()
{
    TRACE_ENTRY_POINT;
    // No implementation.
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MPropertyChangeHandler
// ---------------------------------------------------------
//
void CAlmAlarmControl::HandlePropertyChange(const TUid aCategory, const TUint aKey, const TInt aValue)
{
    TRACE_ENTRY_POINT;
    // Notified when user presses the power key...
    if( aCategory == KPSUidCoreApplicationUIs && aKey == KCoreAppUIsHideAlarm && aValue == ECoreAppUIsHideAlarm )
    {
        /**
        * Does the device have a dedicated power key?
        */
        TBool noPowerKey( EFalse ); // is end key used as a power key?
        TRAPD( err, FeatureManager::InitializeLibL(); )
        ASSERT( !err );

        if( !err )
        {
            noPowerKey = FeatureManager::FeatureSupported( KFeatureIdNoPowerkey );
            FeatureManager::UnInitializeLib();
        }

        if( noPowerKey ) // end key as power key >> snooze
        {
            // cancel the alarm
            if( iGlobalNoteId != KErrNotFound )
            {
                iAlarmUtils->NotifierDialogController()->SetNoteObserver( this );
                iAlarmUtils->NotifierDialogController()->CancelNote( iGlobalNoteId );
            }
        }
        else // stop
        {
            HandleInterruptAlarm( EReasonKSysApHideAlarm );
        }
    }
    // phone state changed
    else if( aCategory == KPSUidStartup && aKey == KPSGlobalSystemState )
    {
        iAlarmUtils->SetDeviceState( static_cast<TPSGlobalSystemState>(aValue) );
        // This is just to make sure the ShowAlarm gets always called because
        // ShowAlarm() is ignored if phone is not in some of it's final states.
        if( IsState( EStateWaitingShowRequest ) )
        {
            ShowAlarm();
        }
    }

    //For plasma support
    else if( aCategory == KPSUidAlarmExtCntl && aKey == KAlarmStopKey && aValue == EAlarmUIStopAlarm )
    {
        //Set the P&S to an uninitialized value
    	TAlarmUIStopAlarm extStopAlarm = EAlarmUIStopAlarmUninitialized;
        PIM_ASSERT( RProperty::Set( KPSUidAlarmExtCntl, KAlarmStopKey, static_cast<TInt>(extStopAlarm)); )

    	ExternalStopAlarm();
    }

    else if( aCategory == KPSUidAlarmExtCntl && aKey == KAlarmSnoozeKey  && aValue == EAlarmUISnoozeAlarm)
    {
        //Set the P&S to an uninitialized value
    	TAlarmUISnoozeAlarm extSnoozeAlarm = EAlarmUISnoozeAlarmUninitialized;
    	PIM_ASSERT( RProperty::Set( KPSUidAlarmExtCntl, KAlarmSnoozeKey, static_cast<TInt>(extSnoozeAlarm)); )

    	ExternalSnoozeAlarm();
    }
	else if( aCategory == KPSUidCoreApplicationUIs && aKey == KLightsAlarmLightActive)
	{
		if(IsState(EStateWaitingInput) && aValue ==  ELightsBlinkingUninitialized )
		{
			iAlarmUtils->SetBackLight(ETrue);
		}
	}
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MNotifierDialogObserver
// ---------------------------------------------------------
//
void CAlmAlarmControl::NoteCompleted(TInt aNoteId, TInt aCommand)
{
    TRACE_ENTRY_POINT;
    if( aNoteId != iGlobalNoteId )  // Valid note?
    {
        TRACE_EXIT_POINT;
        return;
    }

    // cancel timers
    iAlarmUtils->CancelAutoSnooze();
    iAlarmUtils->CancelShutdown();
	
	// do not silence if EAlertOpen or EAknSoftkeyEmpty is received
	if ( EAlertOpen != aCommand && EAknSoftkeyEmpty != aCommand )
		{
		iAlarmUtils->StopAlarmSound();
		}
	if(IsVisible())
	{
		MakeVisible(EFalse);
	}

    switch( iState )
    {
        /**
        * EStateWaitingInput: normal case
        * EStateWaitingDisplayRequest:
        *     This happens only if the global note got handled before we got the DisplayDialogL call.
        *     (e.g. note is dismissed if the cover is closed at the same time when alarm expires)
        **/
        case EStateWaitingInput:
        case EStateWaitingDisplayRequest:
        {
            switch( aCommand )
            {
                case EAlertStop:
                {
                    iGlobalNoteId = KErrNotFound;  // Set note as discarded/used...
                    SetState( EStateAfterInput );
                    iAskWakeup = ETrue; // ask wakeup after all the alarms are handled
                    iAlarmUtils->DoStopAlarm();  // stop
                }
                break;

                case EAlertSnooze:
                {
                    iGlobalNoteId = KErrNotFound;  // Set note as discarded/used...
                    SetState( EStateAfterInput );

                    // show the snooze info note
                    iSnoozeInfoNoteActive = ETrue;
                    SetState( EStateShowingSnoozeInfo );
                    iAlarmUtils->AsyncShowSnoozeInfoNote();
                    iAlarmUtils->TryToSnoozeActiveAlarm();
                }
                break;

                case EAlertSilence:
                {
                    iAlarmUtils->StartAutoSnoozeTimer();  // restart auto-snooze timer
                }
                break;
                
                case EAlertOpen:
                {
                    if( iAlarmUtils->IsCalendarAlarm() && !iAlarmUtils->IsSecurityLockActive() )
	                    {
                        // Do not leave if calendar launch fails. Just continue as normally
                        iAlarmUtils->StopAlarmSound();
                        PIM_TRAPD_ASSERT( iAlarmUtils->StartCalendarL(); )
                        iAlarmUtils->StartAutoSnoozeTimer();  // restart auto-snooze timer
	                    }
                }
                break;

                case EAknSoftkeyEmpty:
                    // Ignore if there is an empty softkey. No functionality to be completed.
                    break;


                default:
                {
                    // Unknown command!
                    Panic( EAlarmUIUnknownCommand | EAlarmUINoteCompleted );
                }
                break;
            }
        }
        break;

        case EStateAskingWakeup:
        {
            iGlobalNoteId = KErrNotFound; // Set note as discarded/used...

            switch( aCommand )
            {
                case EAknSoftkeyYes:
                {
                    SetState( EStateIdle );
                    /*
                    * Going to EStateIdle when phone was started for an alarm will
                    * always start the shutdown timer. Stop the timer before requesting
                    * device startup.
                    */
                    iAlarmUtils->CancelShutdown();

                    // boot up the device
                    iAlarmUtils->DeviceStartup();
                }
                break;

                case EAknSoftkeyNo:
                {
                    // shutdown
                    SetState( EStateIdle );
                }
                break;

                default:
                {
                    // Unknown command!
                    Panic( EAlarmUIUnknownCommand | EAlarmUINoteCompleted );
                }
                break;
            }
        }
        break;

        default:
        {
            // panic - invalid state!
            Panic( EAlarmUIInvalidState | EAlarmUINoteCompleted );
        }
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// From MNotifierDialogObserver
// ---------------------------------------------------------
//
TBool CAlmAlarmControl::DisplayDialogL(TInt aPriority)
{
    TRACE_ENTRY_POINT;
    // Is it our responsibility
    if( aPriority != KAlarmPriority )
    {
        TRACE_EXIT_POINT;
        return EFalse;
    }

    switch( iState )
    {
        case EStateWaitingDisplayRequest:
        {
            iAlarmUtils->StartAutoSnoozeTimer();
            iAlarmUtils->PlayAlarmSound();
            iAlarmUtils->SetKeyGuard( EFalse );
            SetState( EStateWaitingInput );
            iAlarmUtils->StartKeyBlocker();  // block all input for 0.5 seconds
        }
        break;

        case EStateBeforeAskingWakeup:
        {
            SetState( EStateAskingWakeup );
        }
        break;

        default:
        {
            // panic - invalid state!
            Panic( EAlarmUIInvalidState | EAlarmUIDisplayDialog );
        }
    }
    TRACE_EXIT_POINT;
    return EFalse;
}

// ---------------------------------------------------------
// From MNotifierDialogObserver
// ---------------------------------------------------------
//
TBool CAlmAlarmControl::CancelDialog(TInt aPriority)
{
    TRACE_ENTRY_POINT;
    // Is it our responsibility
    if( aPriority != KAlarmPriority )
    {
        TRACE_EXIT_POINT;
        return EFalse;  // -> ignore
    }

    iGlobalNoteId = KErrNotFound;

    /**
    * Reset back to EStateIdle and snooze the alarm if active.
    */
    switch( iState )
    {
        case EStateIdle:
        case EStateShowingSnoozeInfo:
        {
            // fall through
        }
        break;

        case EStateWaitingShowRequest:
        case EStateWaitingDisplayRequest:
        case EStateWaitingInput:
        {
            SetState( EStateIdle );
	          DoCancelDialog();
            StopOrSnoozeAlarm();
        }
        break;

        case EStateBeforeAskingWakeup:
        case EStateAskingWakeup:
        {
            // cancel and shutdown
            iAlarmUtils->CancelAsynchRequest();
            SetState( EStateIdle );
            DoCancelDialog(); // make sure the dialog gets cancelled
        }
        break;

        case EStateAfterInput:
        {
            SetState( EStateIdle );
        }
        break;

        default:
        {
            // panic - invalid state!
            Panic( EAlarmUIUnknownState | EAlarmUICancelDialog );
        }
    }

    TRACE_EXIT_POINT;
    return EFalse;
}

// ---------------------------------------------------------
// From CCoeControl
// ---------------------------------------------------------
//
TKeyResponse CAlmAlarmControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
    TRACE_ENTRY_POINT;
    // Consume all events except softkeys + power and end call key
    // For keycodes see AVKON documentation: Series_60_AVKON_Key_Codes_Modifications_UI_B.doc

    // consume all key presses while key block timer is active
    if( iAlarmUtils->KeyBlockActive() )
    {
        TRACE_EXIT_POINT;
        return EKeyWasConsumed;
    }

    // don't consume any keys while in idle state or showing snooze info note
    if( IsState( EStateIdle ) || iSnoozeInfoNoteActive )
    {
        TRACE_EXIT_POINT;
        return EKeyWasNotConsumed;
    }

    if( (IsState( EStateWaitingInput ) ||
         IsState( EStateAskingWakeup ) )
        && aType == EEventKey )
    {
        switch( aKeyEvent.iCode )
        {
            case EKeyCBA1:     // (scan code EStdKeyDevice0)
            case EKeyCBA2:     // (scan code EStdKeyDevice1)
            case EKeyPowerOff: // (scan code EStdKeyDevice2)
            {
                // no need to let the event through if we don't have an active alarm note
                if( iGlobalNoteId != KErrNotFound )
                {
                    TRACE_EXIT_POINT;
                    return EKeyWasNotConsumed;
                }
                else
                {
                    TRACE_EXIT_POINT;
                    return EKeyWasConsumed;
                }
            }

            // MSK support
            case EKeyOK: // (scan code EStdKeyDevice3)
            {
                // Allow MSK for the "wakeup" query.
                if( IsState( EStateAskingWakeup ) )
                {
                    TRACE_EXIT_POINT;
                    return EKeyWasNotConsumed;
                }
                else
                {
                    if( IsState( EStateWaitingInput ) && 
                        iAlarmUtils->IsCalendarAlarm() && 
                        !iAlarmUtils->IsSecurityLockActive() )
                    {
                        TRACE_EXIT_POINT;
                        return EKeyWasNotConsumed;
                    }

                    TRACE_EXIT_POINT;
                    return EKeyWasConsumed;
                }
            }

            case EKeyPhoneEnd: // (scan code EStdKeyNo)
            {
                // Normally pressing End Call key generates CancelDialog callback, but
                // when we have an active call we don't get the CancelDialog...
                iAlarmUtils->NotifierDialogController()->CancelNote( iGlobalNoteId );  // Cancel alarm....will snooze...
                TRACE_EXIT_POINT;
                return EKeyWasNotConsumed;
            }

            case EKeyVolumeUp:   // (scan code EStdKeyIncVolume)
            case EKeyVolumeDown: // (scan code EStdKeyDecVolume)
            {
                ExternalSnoozeAlarm();  // snooze the alarm
                TRACE_EXIT_POINT;
                return EKeyWasConsumed;
            }

            // OK/selection key, number keys, etc..
            default:
            {
                // let the user "silence" the calendar alarm (=stop flashing & vibra) when
                // using "silent" or "beep once" ringing type.
                // !!! calendar alarm uses "silence" key if ringing type is not "silent" or "beep once"
                if( !iAlarmUtils->IsClockAlarm() && iAlarmUtils->IsRingingTypeSilent() )
                {
                    iAlarmUtils->StopAlarmSound();
                }

                // Eat all other keys...
                // To enable keys (numbers, etc.) remember to re-evaluate
                // all the switch...case Panics...
                TRACE_EXIT_POINT;
                return EKeyWasConsumed;
            }
        }
    }

    // consume all other key presses if phone startup is ready
    if( iAlarmUtils->IsPhoneStartupReady() )
    {
        TRACE_EXIT_POINT;
        return EKeyWasConsumed;
    }
    else // still booting (alarm might be waiting to show the notification while phone is still in PIN query)
    {
        TRACE_EXIT_POINT;
        return EKeyWasNotConsumed;
    }
}

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
void CAlmAlarmControl::ShowSnoozeInfoNoteL()
{
    TRACE_ENTRY_POINT;

    //Changes for MPIN-73VCR2
   HBufC* stringHolder = NULL;
   CAknInformationNote* note = new (ELeave) CAknInformationNote();
   TAlarmSecondaryDisplayNote alarmSecDispNote = EAlarmNoNote;

   if( iAlarmUtils->AlarmData().iSnoozeTime == 1 )
    {
        stringHolder = StringLoader::LoadLC( R_EIKALARM_NOTE_SNOOZE_ONE );
	      alarmSecDispNote = EAlarmSingleMinuteSnooze;
    }
   else
    {
        stringHolder = StringLoader::LoadLC( R_EIKALARM_NOTE_SNOOZE, iAlarmUtils->AlarmData().iSnoozeTime );
        alarmSecDispNote = EAlarmMutlipleMinuteSnooze;
    }

   CleanupStack::PushL( note );
   note->PublishDialogL(alarmSecDispNote,KAlarmUINoteCategory);
   CleanupStack::Pop();

   TPtr bufPtr = stringHolder->Des();
   AknTextUtils::DisplayTextLanguageSpecificNumberConversion( bufPtr );

		//Commit data for buffer
		CAknMediatorFacade* covercl1 = AknMediatorFacade(note);
		if (covercl1) // returns null if __COVER_DISPLAY is not defined
	    {
		    covercl1->BufStream().WriteInt32L( iAlarmUtils->AlarmData().iSnoozeTime );// for coverui localisation info
		    covercl1->BufStream().CommitL(); // no more data to send so commit buf
	    }
	  note->ExecuteLD( *stringHolder );

		CleanupStack::PopAndDestroy(); //stringHolder

    // End of changes for MPIN-73VCR2

    iSnoozeInfoNoteActive = EFalse;

    // new alarm expired during the snooze info note --> show it
    if( IsState( EStateWaitingShowRequest ) )
    {
        ShowAlarm();
    }
    else
    {
        SetState( EStateIdle );
    }
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// Stops an active alarm.
// Has the same effect as pressing the power key (i.e. if
// the device was set off the startup query won't be shown)
// ---------------------------------------------------------
//
void CAlmAlarmControl::ExternalStopAlarm()
{
    TRACE_ENTRY_POINT;
    /**
    * External commands should be handled only if we are
    * really expecting some input from the user...
    */
    if( IsState( EStateWaitingInput ) )
    {
        iAlarmUtils->CancelAutoSnooze();
        iAskWakeup = EFalse; // don't show the wakeup query!
        SetState( EStateAfterInput );
        iAlarmUtils->DoStopAlarm();  // stop
        DoCancelDialog();
    }
    iAlarmUtils->SetCalendarAlarmViewer(EFalse);
    TRACE_EXIT_POINT;
}

// ---------------------------------------------------------
// Snoozes an active alarm.
// ---------------------------------------------------------
//
void CAlmAlarmControl::ExternalSnoozeAlarm()
{
    TRACE_ENTRY_POINT;
    /**
    * External commands should be handled only if we are
    * really expecting some input from the user...
    */
    if( IsState( EStateWaitingInput ) )
    {
        iAlarmUtils->CancelAutoSnooze();
        SetState( EStateAfterInput );

        if( iAlarmUtils->CanSnooze() )
        {
            // show the snooze info note
            iSnoozeInfoNoteActive = ETrue;
            SetState( EStateShowingSnoozeInfo );
            iAlarmUtils->AsyncShowSnoozeInfoNote();
        }
        // snooze (or stop, if max snooze count passed) the alarm and cancel the dialog
        iAlarmUtils->TryToSnoozeActiveAlarm();
        DoCancelDialog();
    }
    iAlarmUtils->SetCalendarAlarmViewer(EFalse);
    TRACE_EXIT_POINT;
}

/**
* Return if alarm can be snoozed.
* @since 5.0
**/
TBool CAlmAlarmControl::CanSnooze()
 	{
 		return iAlarmUtils->CanSnooze();
 	}

//---------------------------------------------------------
// CAlmAlarmControl::HandleAlmInfoCRChangeL
// Handles Missed Alarm Store notifications
//---------------------------------------------------------
//
void CAlmAlarmControl::HandleAlmInfoCRChangeL(TUint32 /*aCount*/)
    {
    TRACE_ENTRY_POINT; 

    TRACE_EXIT_POINT;
    }

//---------------------------------------------------------
// CAlmAlarmControl::SetStopFromContext
// Sets if Stop to be sent to calendar
//---------------------------------------------------------
 void CAlmAlarmControl::SetStopFromContext(TBool aStopFromContext)
 {
 	iStopFromContextFw = aStopFromContext;
 }

//---------------------------------------------------------
// CAlmAlarmControl::IsStopFromContext
// Gets if Stop/StopAndExit to be sent to calendar
//---------------------------------------------------------
//
 TBool CAlmAlarmControl::IsStopFromContext()
 {
 	return iStopFromContextFw;
 }

 CAlarmUtils* CAlmAlarmControl::AlarmUtils() const
     {
     return iAlarmUtils;
     }
 // End of File