satengine/SatServer/Commands/DisplayTextCmd/src/CDisplayTextHandler.cpp
changeset 0 ff3b6d0fd310
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/satengine/SatServer/Commands/DisplayTextCmd/src/CDisplayTextHandler.cpp	Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,539 @@
+/*
+* Copyright (c) 2002-2008 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:  Handles DisplayText command
+*
+*/
+
+
+#include    <MSatShellController.h>
+#include    "MSatApi.h"
+#include    "MSatUtils.h"
+#include    "MSatSystemState.h"
+#include    "MSatUiSession.h"
+#include    "SatSOpcodes.h"
+#include    "MSatSUiClientHandler.h"
+#include    "CDisplayTextHandler.h"
+#include    "CClearScreenHandler.h"
+#include    "SatLog.h"
+
+const TInt8 KSecondsInMinute = 60;
+const TInt8 KSecond = 10;
+const TUint8 KHalfSecond = 5;
+
+// ======== MEMBER FUNCTIONS ========
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::CDisplayTextHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CDisplayTextHandler::CDisplayTextHandler() :
+    CSatCommandHandler(),
+    iDisplayTextData(),
+    iDisplayTextPckg( iDisplayTextData ),
+    iDisplayTextRsp(),
+    iDisplayTextRspPckg( iDisplayTextRsp ),
+    iDisplayTextSendData(),
+    iDisplayTextSendPckg( iDisplayTextSendData )
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: \
+        CDisplayTextHandler::CDisplayTextHandler calling - exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::ConstructL()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ConstructL calling" )
+
+    // Register service request handler for DisplayText command
+    iUtils->RegisterServiceRequestL(
+        ESatSProactiveDisplayText,
+        ESatSProactiveDisplayTextResponse,
+        this );
+
+    iClearScreenHandler = CClearScreenHandler::NewL( *iUtils );
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ConstructL exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CDisplayTextHandler* CDisplayTextHandler::NewL( MSatUtils* aUtils )
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::NewL calling" )
+
+    CDisplayTextHandler* self = new( ELeave ) CDisplayTextHandler;
+
+    CleanupStack::PushL( self );
+    self->BaseConstructL( aUtils );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::NewL exiting" )
+    return self;
+    }
+
+// Destructor
+CDisplayTextHandler::~CDisplayTextHandler()
+    {
+    LOG( SIMPLE,
+        "DISPLAYTEXT: CDisplayTextHandler::~CDisplayTextHandler calling" )
+
+    Cancel();
+    delete iClearScreenHandler;
+
+    LOG( SIMPLE,
+        "DISPLAYTEXT: CDisplayTextHandler::~CDisplayTextHandler exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::ClientResponse
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::ClientResponse()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ClientResponse calling" )
+
+    // SatShellController checks if SatUi was brought to foreground from
+    // background and set SatUi background again.
+    if ( RSat::EHighPriority == iDisplayTextData.iPriority )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ClientResponse \
+             set SatUi background" )
+        iUtils->SatUiHandler().ShellController().SetSatUiToBackground();
+        }
+
+    TBool terminatedByUser( EFalse );
+    if ( RSat::KPSessionTerminatedByUser == iDisplayTextRsp.iGeneralResult )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ClientResponse \
+             session terminated by user" )
+        terminatedByUser = ETrue;
+
+        iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
+        }
+
+    // Check immediate response. If true, no need to send TerminalResponse
+    // This must be checked from our own member variable, because
+    // ClearScreenHandler may have this value set to false already if the
+    // timer has run out and screen was cleared.
+    if ( iImmediateResponse )
+        {
+        // Check has sustained text cleared in ClearScreen handler
+        if ( !iImmediatePending )
+            {
+            // No need to send terminal response since it is already sent.
+            iImmediateResponse = EFalse;
+
+            // Notify sustained text removal, if not yet notified.
+            iUtils->NotifyEvent( MSatUtils::ESustainedTextRemoved );
+            iClearScreenHandler->UpdateImmediateState( EFalse );
+
+            if ( !iUtils->SatUiHandler().UiLaunchedByUser() ||
+                 terminatedByUser )
+                {
+                LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::\
+                     ClientResponse close ui session" )
+                // Next SimSession end will close the ui session.
+                iUtils->NotifyEvent( MSatUtils::ESessionTerminatedByUser );
+                }
+            else
+                {
+                LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::\
+                     ClientResponse others" )
+                // If SATUI client application is running, show the setup menu.
+                if ( iUtils->SatUiHandler().UiSession() )
+                    {
+                    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::\
+                         ClientResponse SetUpMenu" )
+                    iUtils->NotifyEvent( MSatUtils::ESetUpMenuNeeded );
+                    }
+                }
+            }
+        iImmediatePending = EFalse;
+        }
+    else
+        {
+        LOG( SIMPLE,
+            "DISPLAYTEXT: CDisplayTextHandler::ClientResponse Success" )
+        // Generate terminal response
+        iDisplayTextRsp.SetPCmdNumber( iDisplayTextData.PCmdNumber() );
+        TerminalRsp( RSat::EDisplayText, iDisplayTextRspPckg );
+        }
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::ClientResponse exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::DoCancel
+// Cancels the sat request.
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::DoCancel()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::DoCancel calling" )
+
+    iUtils->USatAPI().NotifyDisplayTextCancel();
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::DoCancel exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::IssueUSATRequest
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::IssueUSATRequest( TRequestStatus& aStatus )
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::IssueUSATRequest calling" )
+
+    // Clear the IPC package.
+    new (&iDisplayTextData) RSat::TDisplayTextV2();
+    iDisplayTextRsp.iGeneralResult = RSat::KPSessionTerminatedByUser; // default
+    iDisplayTextSendData.iDuration = 0;
+    iDisplayTextSendData.iClearScreen = RSat::EClearScreenTriggerNotSet;
+
+    iUtils->USatAPI().NotifyDisplayText( aStatus, iDisplayTextPckg );
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::IssueUSATRequest exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::CommandAllowed
+// -----------------------------------------------------------------------------
+//
+TBool CDisplayTextHandler::CommandAllowed()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed calling" )
+
+    // By default, this is true.
+    TBool commandAllowed( ETrue );
+
+    const TBool callIncoming( iUtils->SystemState().IsCallIncoming() );
+    const TBool phoneInIdle( IsPhoneInIdleState() );
+
+    
+    TBool screenSaver( EFalse );
+    
+    // By default, this is true.    
+    TBool uiNotReady( ETrue );     
+    
+    // If screen saver is actived from idle.
+    screenSaver = iUtils->SystemState().IsScreenSaverActivedFromIdle();
+      
+    if ( screenSaver )
+        {
+        uiNotReady = EFalse;
+        }
+    else
+        {
+        uiNotReady = ( !phoneInIdle  &&
+                     ( !iUtils->SatUiHandler().UiSession() ) );        
+        }
+
+    const RSat::TDisplayPriority priority( iDisplayTextData.iPriority );
+
+    // Icon without text
+    if ( ( 0 == iDisplayTextData.iText.Length() ) &&
+         ( RSat::ENotSelfExplanatory == iDisplayTextData.iIconId.iQualifier ||
+           RSat::ESelfExplanatory == iDisplayTextData.iIconId.iQualifier ) )
+        {
+        iDisplayTextRsp.iGeneralResult = RSat::KCmdDataNotUnderstood;
+        iDisplayTextRsp.iInfoType = RSat::KNoAdditionalInfo;
+        iDisplayTextRsp.iAdditionalInfo.Zero();
+        commandAllowed = EFalse;
+        }
+    // Check is call incoming or if Normal priority check is call ongoing or is
+    // phone in idle state and is there UiSession. AND Ui is not closing
+    else if ( callIncoming ||
+         ( ( priority == RSat::ENormalPriority ) &&
+           ( uiNotReady ) ) )
+        {
+        // Check is UI closing
+        if ( !iUtils->SatUiHandler().IsUiClosing() )
+            {
+            // Generate proper terminal response and send it.
+            // By default, this command does not have additional information,
+            // except in this case when screen is busy.
+            iDisplayTextRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+            iDisplayTextRsp.iInfoType = RSat::KMeProblem;
+            iDisplayTextRsp.iAdditionalInfo.SetLength( 1 );
+            iDisplayTextRsp.iAdditionalInfo[0] = RSat::KScreenBusy;
+
+            // Command is not allowed.
+            LOG( SIMPLE,
+                "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed Not allowed" )
+            commandAllowed = EFalse;
+            }
+        else // UI is closing, command is allowed. UI is launched again when it
+             // has been fully closed
+            {
+            LOG( SIMPLE,
+                "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed Ui is closing\
+                Command is allowed" )
+            }
+        }
+    else
+        {
+        LOG( SIMPLE,
+                "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed Allowed" )
+        }
+
+    if ( !commandAllowed )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed \
+             commandAllowed false" )
+        iDisplayTextRsp.SetPCmdNumber( iDisplayTextData.PCmdNumber() );
+        TerminalRsp( RSat::EDisplayText, iDisplayTextRspPckg );
+        }
+
+    LOG2( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::CommandAllowed exiting,\
+          commandAllowed: %d", commandAllowed )
+    return commandAllowed;
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::NeedUiSession
+// -----------------------------------------------------------------------------
+//
+TBool CDisplayTextHandler::NeedUiSession()
+    {
+    // Priority and phone idle state is checked in CommandAllowed function, so
+    // in this case it has passed and we need UI.
+    LOG( NORMAL,
+        "DISPLAYTEXT: CDisplayTextHandler::NeedUiSession calling - calling" )
+
+    // Notify Mediator if Cover UI is supported
+    if ( iUtils->CoverUiSupported() )
+        {
+        TSatCommandData medEventData;
+        medEventData.iPCmdNumber = RSat::EDisplayText;
+        medEventData.iAlphaId.iStatus = RSat::EAlphaIdProvided;
+        medEventData.iAlphaId.iAlphaId.Copy( iDisplayTextData.iText );
+        if ( RSat::ETimeUnitNotSet == iDisplayTextData.iDuration.iTimeUnit &&
+            RSat::EClearAfterDelay == iDisplayTextData.iClearScreenTrigger )
+            {
+            LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::NeedUiSession \
+                 KSatDefaultDuration" )
+            medEventData.iDuration.iTimeUnit = RSat::ESeconds;
+            medEventData.iDuration.iNumOfUnits = KSatDefaultDuration;
+            }
+        else if (
+            ( RSat::ETimeUnitNotSet == iDisplayTextData.iDuration.iTimeUnit ) &&
+            ( RSat::EUserClear == iDisplayTextData.iClearScreenTrigger ) )
+            {
+            LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::NeedUiSession \
+                 KSatLongDuration" )
+            medEventData.iDuration.iTimeUnit = RSat::ESeconds;
+            medEventData.iDuration.iNumOfUnits = KSatLongDuration;
+            }
+        else
+            {
+            LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::NeedUiSession \
+                 others" )
+            medEventData.iDuration = iDisplayTextData.iDuration;
+            }
+
+        medEventData.iIconID = iDisplayTextData.iIconId;
+        TSatCommandPckg tPckg( medEventData );
+        iUtils->RaiseSatEvent( tPckg );
+        }
+
+    LOG( NORMAL,
+        "DISPLAYTEXT: CDisplayTextHandler::NeedUiSession - exiting" )
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::HandleCommand
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::HandleCommand()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand calling" )
+
+    // If this is a High priority message, bring SatUi to foreground.
+    if ( RSat::EHighPriority == iDisplayTextData.iPriority )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand bring \
+             SatUi to foreground" )
+        iUtils->SatUiHandler().ShellController().BringSatUiToForeground();
+        }
+
+    // Notify must be here, because it triggers ClearScreen and
+    // this notify must be before UpdateImmediateState function call.
+    iUtils->NotifyEvent( MSatUtils::EDisplayTextExecuting );
+
+    // Send terminal response immediately if SIM requires it.
+    if ( RSat::EImmediateRsp == iDisplayTextData.iImmediateRsp )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand \
+             immediate response" )
+        // There is sustained text already on display
+        if ( iImmediateResponse )
+            {
+            LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand \
+                 iImmediateResponse true" )
+            iImmediatePending = ETrue;
+            }
+
+        // Generate terminal response
+        iDisplayTextRsp.iGeneralResult = RSat::KSuccess;
+        iDisplayTextRsp.iInfoType = RSat::KNoAdditionalInfo;
+        iDisplayTextRsp.iAdditionalInfo.Zero();
+        iDisplayTextRsp.SetPCmdNumber( iDisplayTextData.PCmdNumber() );
+
+        // We cannot use CSatCommandHandler's TerminalRsp here because it
+        // restarts the request and we are not yet ready for that
+        iUtils->NotifyEvent( MSatUtils::EDelaySimSessionEnd );
+
+        iUtils->USatAPI().TerminalRsp(
+            RSat::EDisplayText, iDisplayTextRspPckg );
+
+        iImmediateResponse = ETrue;
+        iClearScreenHandler->UpdateImmediateState( ETrue );
+
+        iUtils->NotifyEvent( MSatUtils::ESustainedTextInDisplay );
+
+        // Inform UI that this is sustained text
+        iDisplayTextSendData.iSustainedText = ETrue;
+        }
+    else
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand \
+             others" )
+        // Reset information for other cases.
+        // Inform UI that this is not sustained text.
+        iDisplayTextSendData.iSustainedText = EFalse;
+        }
+
+    // Check if duration data is available.
+    if ( ( RSat::ENoDurationAvailable != iDisplayTextData.iDuration.iTimeUnit )
+        && ( RSat::ETimeUnitNotSet != iDisplayTextData.iDuration.iTimeUnit )
+        && iDisplayTextData.iDuration.iNumOfUnits )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand \
+             duration data available" )
+        // The resolution of a timer is 1 second.
+        TTimeIntervalSeconds duration( 0 );
+        duration = DurationInSeconds( iDisplayTextData.iDuration );
+        iDisplayTextSendData.iDuration = duration;
+        }
+
+    // Build the IPC Package.
+    iDisplayTextSendData.iText = iDisplayTextData.iText;
+    iDisplayTextSendData.iSimApplicationName = iUtils->SatAppName();
+    iDisplayTextSendData.iPCmdNumber = iDisplayTextData.PCmdNumber();
+    iDisplayTextSendData.iIconId = iDisplayTextData.iIconId;
+    iDisplayTextSendData.iClearScreen = iDisplayTextData.iClearScreenTrigger;
+
+    // Now we can send command to client.
+    MSatUiSession* uiSession = iUtils->SatUiHandler().UiSession();
+    uiSession->SendCommand(
+        &iDisplayTextSendPckg,
+        &iDisplayTextRspPckg,
+        ESatSProactiveDisplayText );
+
+    // Restart request, if immediate response.
+    if ( RSat::EImmediateRsp == iDisplayTextData.iImmediateRsp )
+        {
+        LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand \
+             immediate response" )
+        // Renew the request
+        Start();
+        }
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::HandleCommand exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::UiLaunchFailed
+// -----------------------------------------------------------------------------
+//
+void CDisplayTextHandler::UiLaunchFailed()
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::UiLaunchFailed calling" )
+
+    // Send terminal response
+    iDisplayTextRsp.iGeneralResult = RSat::KMeUnableToProcessCmd;
+    iDisplayTextRsp.iInfoType = RSat::KMeProblem;
+    iDisplayTextRsp.iAdditionalInfo.SetLength( 1 );
+    iDisplayTextRsp.iAdditionalInfo[0] = RSat::KNoSpecificMeProblem;
+    iDisplayTextRsp.SetPCmdNumber( iDisplayTextData.PCmdNumber() );
+    TerminalRsp( RSat::EDisplayText, iDisplayTextRspPckg );
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::UiLaunchFailed exiting" )
+    }
+
+// -----------------------------------------------------------------------------
+// CDisplayTextHandler::DurationInSeconds
+// Return duration in seconds.
+// -----------------------------------------------------------------------------
+//
+TTimeIntervalSeconds CDisplayTextHandler::DurationInSeconds(
+    const RSat::TDuration& aDuration ) const
+    {
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::DurationInSeconds calling" )
+
+    TTimeIntervalSeconds duration( 0 );
+    LOG2( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::DurationInSeconds \
+          aDuration.iTimeUnit: %d", aDuration.iTimeUnit )
+    switch ( aDuration.iTimeUnit )
+        {
+        case RSat::EMinutes:
+            {
+            duration = aDuration.iNumOfUnits * KSecondsInMinute;
+            break;
+            }
+
+        case RSat::ESeconds:
+            {
+            duration = aDuration.iNumOfUnits;
+            break;
+            }
+
+        case RSat::ETenthsOfSeconds:
+            {
+            // If duration exists minimum values is 1 second
+            if ( aDuration.iNumOfUnits < KHalfSecond )
+                {
+                LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::\
+                     DurationInSeconds aDuration.iNumOfUnits < KHalfSecond" )
+                duration = KSecond;
+                }
+            else
+                {
+                // Make Roundup
+                duration = ( aDuration.iNumOfUnits + KHalfSecond ) / KSecond;
+                }
+            break;
+            }
+
+        default:
+            {
+            //duration is 0
+            break;
+            }
+        }
+
+    LOG( SIMPLE, "DISPLAYTEXT: CDisplayTextHandler::DurationInSeconds exiting" )
+    return duration;
+    }