codhandler/codui/src/CodAppUi.cpp
changeset 0 dd21522fd290
child 37 cb62a4f66ebe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/codhandler/codui/src/CodAppUi.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,1206 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:  Implementation of class CCodAppUi.
+*
+*/
+
+
+#include <avkon.hrh>
+#include <eikbtgpc.h>
+#include <eikapp.h>
+#include <apgcli.h>
+#include <CodUi.rsg>
+#include <avkon.rsg>
+#include <AknQueryDialog.h>
+#include <ErrorUi.h>
+#include <TextResolver.h>
+#include <AiwGenericParam.h>
+#include <DocumentHandler.h>
+#include <DcfRep.h>
+#include <RoapDef.h>
+#include <DRMCommon.h>
+#include <StringLoader.h>
+#include <CodEng.h>
+#include <CodData.h>
+#include <CodError.h>
+#include <CodStatus.h>
+#include <CodUtil.h>
+#include <RoapData.h>
+#include "CodAppUi.h"
+#include "CodView.h" 
+#include "CodDocument.h" 
+#include "CodWaitDialog.h" 
+#include "CodUi.hrh"
+#include "CodUiPanic.h"
+#include "RequestCompleteCallback.h"
+#include "CodUiResource.h"
+#include "CodLogger.h"
+#include "CodDialog.h"
+
+// ================= CONSTANTS =======================
+
+/// UID of Wml Browser.
+LOCAL_D const TInt KCodWmlBrowserUid = 0x10008D39;
+
+/// Message prefix, to launch browser with URL.
+_LIT( KCodMsgLaunchBrowserWithUrl, "4 " );
+
+/// Reserved word "local".
+_LIT8( KCodReservedWordLocal, "local" );
+
+/// Reserved word "back".
+_LIT8( KCodReservedWordBack, "back" );
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ----------------------------------------------------------
+// CCodAppUi::CodDocument()
+// ----------------------------------------------------------
+//
+CCodDocument* CCodAppUi::CodDocument()
+    {
+    // Inline method must be defined before it is used.
+    return STATIC_CAST( CCodDocument*, Document() );
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::CCodAppUi()
+// ----------------------------------------------------------
+//
+CCodAppUi::CCodAppUi( TBool aCod )
+: iCod( aCod ),
+  iCurrentCba( R_AVKON_SOFTKEYS_BACK ),
+  iError( KErrNone ),
+  iSilentMode( EFalse ),
+  iSuppressNextUrl( EFalse ),
+  iSuppressLaunch( EFalse ),
+  iRoap( EFalse )
+    {
+    CLOG(( 2, _L("*** CCodAppUi::CCodAppUi") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::ConstructL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::ConstructL()
+    {
+    iCodResource = CCodUiResource::NewL( *iEikonEnv );
+    BaseConstructL( EAknEnableMSK );
+    CodDocument()->Model().SetObserver( this );    
+    iView = new (ELeave) CCodView;
+    iView->SetMopParent( this );
+    iView->ConstructL();
+    iView->SetRect( ClientRect() );
+    iView->ActivateL();
+    iCallback = new ( ELeave ) CRequestCompleteCallback();
+    iErrorUi = CErrorUI::NewL( *iCoeEnv );
+    HandleModelChangeL();   // Initialize view with data.
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::~CCodAppUi()
+// ----------------------------------------------------------
+//
+CCodAppUi::~CCodAppUi()
+    {
+    CLOG(( 2, _L("*** -> CCodAppUi::~CCodAppUi") ));
+    delete iDocHandler;
+    delete iDocParams;
+    // First of all NULL out observer to avoid further callbacks.
+    CodDocument()->Model().SetObserver( NULL );
+    // We must Cancel the model before deleting the callback.
+    CodDocument()->Model().Cancel();
+    delete iCallback;
+    delete iErrorUi;
+    delete iWaitNote;
+    delete iView;
+    if ( iDoorObserver )
+        {
+        iDoorObserver->NotifyExit( MApaEmbeddedDocObserver::ENoChanges );
+        }
+    delete iCodResource;
+    iFs.Close();
+    CLOG(( 2, _L("<- CCodAppUi::~CCodAppUi") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::OpenFileDone()
+// ----------------------------------------------------------
+//
+void CCodAppUi::OpenFileDone( TInt aError )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::OpenFileDone aError(%d)"), aError ));
+    iError = aError;
+    TRAPD( err, OpenFileDoneL() );
+    if ( err )
+        {
+        RunAppShutter();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::OpenFileDone") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::SetServiceFlow()
+// ----------------------------------------------------------
+//
+void CCodAppUi::SetServiceFlow
+        (
+        TBool aSilentMode,
+        TBool aSuppressNextUrl,
+        TBool aSuppressLaunch
+        )
+    {
+    CLOG(( 2, \
+        _L("CCodAppUi::SetServiceFlow silent(%d) noUrl(%d) noLaunch(%d)"), \
+        aSilentMode, aSuppressNextUrl, aSuppressLaunch ));
+    iSilentMode = aSilentMode;
+    iSuppressNextUrl = aSuppressNextUrl;
+    iSuppressLaunch = aSuppressLaunch;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleModelChangeL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::HandleModelChangeL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::HandleModelChangeL") ));
+    TInt commandSet( R_AVKON_SOFTKEYS_BACK );
+    const CCodData& data = CodDocument()->Model().Data();
+    if ( data.IsValid() )
+        {
+        // Valid data: show details, show buttons "Accept" / "Reject".
+        iView->SetDataL( data, iCod );
+        commandSet = R_COD_UI_CBA_ACCEPT_REJECT;
+        }
+    else
+        {
+        // Invalid data: don't show details, show button "Back".
+        iView->Clear();
+        commandSet = R_AVKON_SOFTKEYS_BACK;
+        }
+    SetCbaL( commandSet );
+    CLOG(( 2, _L("<- CCodAppUi::HandleModelChangeL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::OpenFileL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::OpenFileL( const TDesC& aFileName )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::OpenFileL aFileName<%S>"), &aFileName ));
+    Document()->OpenFileL( ETrue, aFileName, iCoeEnv->FsSession() );
+    CLOG(( 2, _L("<- CCodAppUi::OpenFileL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleCommandL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::HandleCommandL( TInt aCommand )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::HandleCommandL aCommand(%d)"), \
+        aCommand ));
+    switch ( aCommand )
+        {
+        // From blank screen show during startup (incl. parsing).
+        case EAknSoftkeyBack:
+        // CAknShutter generated command.
+        case EEikCmdExit:
+            {
+            Exit();
+            break;
+            }
+
+        case EAknSoftkeyEmpty:
+            {
+            break;
+            }
+
+        case ECodUiCmdAccept:
+            {
+            // Safety code: ignore commands until completion of previous.
+            // Quite unlikely to happen as we don't have this CBA.
+            if( !CodDocument()->Model().IsActive() )
+                {
+                SetCbaL( R_AVKON_SOFTKEYS_EMPTY );
+                CodDocument()->Model().Accept( &iCallback->iStatus );
+                // Exit after processing is done.
+                iCallback->CallbackOnCompletion
+                    ( TCallBack( StaticLoadDone, this ) );
+                }
+            break;
+            }
+
+        case ECodUiCmdReject:
+            {
+            // Safety code: ignore commands until completion of previous.
+            // Quite unlikely to happen as we don't have this CBA.
+            if( !CodDocument()->Model().IsActive() )
+                {
+                SetCbaL( R_AVKON_SOFTKEYS_EMPTY );
+                CodDocument()->Model().Reject( &iCallback->iStatus );
+                iCallback->CallbackOnCompletion
+                    ( TCallBack( StaticLoadDone, this ) );
+                }
+            break;
+            }
+
+        case ECodUiCmdCancel:
+            {
+            CodDocument()->Model().Stop();
+            break;
+            }
+
+        default:
+            {
+            CLOG(( 0, _L("  unknown command") ));
+            __ASSERT_DEBUG
+                ( EFalse, CodUiPanic( ECodUiUnknownCommand ) );
+            break;
+            }
+        }
+    CLOG(( 2, _L("<- CCodAppUi::HandleCommandL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::ProcessCommandParametersL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::ProcessCommandParametersL
+( TApaCommand aCommand, TFileName& /*aDocumentName*/, const TDesC8& /*aTail*/ )
+    {
+    if ( aCommand == EApaCommandOpen )
+        {
+        CLOG(( 2, _L("CCodAppUi::ProcessCommandParametersL: EApaCommandOpen - noop") ));
+        // Do not handle this here - CAiwGenericParamList not ready
+        //OpenFileL( aDocumentName );
+        }
+    return EFalse;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleKeyEventL()
+// ----------------------------------------------------------
+//
+TKeyResponse CCodAppUi::HandleKeyEventL
+( const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::HandleKeyEventL") ));
+    CLOG(( 3, _L("  aKeyEvent.iCode(%d)"), aKeyEvent.iCode ));
+    CLOG(( 3, _L("  aKeyEvent.iScanCode(%d)"), aKeyEvent.iScanCode ));
+    CLOG(( 3, _L("  aKeyEvent.iModifiers(%d)"), aKeyEvent.iModifiers ));
+    CLOG(( 3, _L("  aKeyEvent.iRepeats(%d)"), aKeyEvent.iRepeats ));
+    CLOG(( 3, _L("  aType(%d)"), aType ));
+    TKeyResponse result = EKeyWasNotConsumed;
+    if (
+        ( aKeyEvent.iCode == EKeyOK || aKeyEvent.iCode == EKeyEnter ) &&
+        ( !(aKeyEvent.iModifiers & EModifierShift) ) &&
+        ( iCurrentCba == R_COD_UI_CBA_ACCEPT_REJECT )
+       )
+        {
+        // Selection key press is same as Accept softkey (provided we have
+        // the Accept softkey).
+        HandleCommandL( ECodUiCmdAccept );
+        result = EKeyWasConsumed;
+        }
+    else if ( aKeyEvent.iCode == EKeyPhoneEnd &&
+              iCurrentCba == R_COD_UI_CBA_ACCEPT_REJECT )
+        {
+        // Red key press -> Reject.
+        HandleCommandL( ECodUiCmdReject );
+        result = EKeyWasConsumed;
+        }
+    else
+        {
+        result = iView->OfferKeyEventL( aKeyEvent, aType );
+        }
+    CLOG(( 2, _L("<- CCodAppUi::HandleKeyEventL returns (0x%x)"), \
+                                                                    result ));
+    return result;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleResourceChangeL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::HandleResourceChangeL( TInt aType )
+    {
+    CAknAppUi::HandleResourceChangeL( aType );
+    if ( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        iView->SetRect( ClientRect() );
+        }
+    iView->HandleResourceChange( aType );
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::GetRootPathL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::GetRootPathL( TDes& aRootPath )
+    {
+    CLOG(( 2, _L("CCodAppUi::GetRootPathL") ));
+    CodDialog::GetRootPathL( aRootPath );
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::StartLoadL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::StartLoadL( TInt aStatusCode )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::StartLoadL aStatusCode(%d)"), \
+        aStatusCode ));
+    __ASSERT_DEBUG( !iWaitNote, CodUiPanic( ECodUiInternal ) );
+
+    TInt resId = R_QTN_CD_WAIT_PLEASE_WAIT;
+    if ( aStatusCode == KHttp900Success )
+        {
+        resId = R_QTN_CD_WAIT_DOWNLOADING;
+        }
+    else if ( aStatusCode == KHttp921UserAborted )
+        {
+        resId = R_QTN_CD_WAIT_REJECT;
+        }
+    iWaitNote = new (ELeave) CCodWaitDialog
+        ( REINTERPRET_CAST( CEikDialog**, &iWaitNote ), *this );
+    iWaitNote->PrepareLC( R_COD_UI_WAIT_NOTE );
+    iWaitNote->SetTextL( resId );
+    iWaitNote->RunLD();
+    CLOG(( 2, _L("<- CCodAppUi::StartLoadL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::StartCancelL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::StartCancelL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::StartCancelL") ));
+    __ASSERT_DEBUG( iWaitNote, CodUiPanic( ECodUiInternal ) );
+    iWaitNote->SetTextL( R_QTN_CD_WAIT_REJECT );
+    CLOG(( 2, _L("<- CCodAppUi::StartCancelL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::ProgressL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::ProgressL( TInt /*aFinalValue*/, TInt /*aCurrentValue*/ )
+    {
+    // TODO
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::Done()
+// ----------------------------------------------------------
+//
+void CCodAppUi::Done( TInt LOG_ONLY( aStatusCode ), TInt LOG_ONLY( aError ) )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::Done aStatusCode(%d) aError(%d)"), \
+        aStatusCode, aError ));
+    delete iWaitNote;
+    iWaitNote = NULL;
+    CLOG(( 2, _L("<- CCodAppUi::Done") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::ConfirmConnectL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::ConfirmConnectL()
+    {
+    CLOG(( 2, _L("CCodAppUi::ConfirmConnectL") ));
+    return CodDialog::ConfirmConnectL();
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::StartConnect()
+// ----------------------------------------------------------
+//
+void CCodAppUi::StartConnect( TUint32 LOG_ONLY( aIap ) )
+    {
+    CLOG(( 2, _L("CCodAppUi::StartConnect aIap(%d)"), aIap ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::EndConnect()
+// ----------------------------------------------------------
+//
+void CCodAppUi::EndConnect()
+    {
+    CLOG(( 2, _L("CCodAppUi::EndConnect") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::WaitForLicenseL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::WaitForLicenseL()
+    {
+    CLOG(( 2, _L("CCodAppUi::WaitForLicenseL") ));
+    }
+
+
+// ----------------------------------------------------------
+// CCodAppUi::UserAuthL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::UserAuthL
+        (
+        const TDesC& LOG_ONLY( aHost ),
+        const TDesC& LOG_ONLY( aRealm ),
+        TBool LOG_ONLY( aProxyAuth ),
+        TDes& aUsername,
+        TDes& aPassword
+        )
+    {
+    CLOG(( 2, _L("CCodAppUi::UserAuthL") ));
+    CLOG(( 3, _L("  aHost<%S>"), &aHost ));
+    CLOG(( 3, _L("  aRealm<%S>"), &aRealm ));
+    CLOG(( 3, _L("  aProxyAuth(0x%x)"), aProxyAuth ));
+    // Feature dropped - empty implementation.
+    aUsername.Zero();
+    aPassword.Zero();
+    return ETrue;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::RoapTriggerParsedL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::RoapTriggerParsedL( const CRoapData& aData )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::RoapTriggerParsedL") ));
+    iRoap = ETrue;
+    if ( aData.iContextStatus == Roap::EInvalidContext )
+        {
+        // No valid RI context, ROAP will involve device registration.
+        // User must confirm.
+        CLOG(( 4, _L("  invalid context") ));
+        CAknQueryDialog* dialog = CAknQueryDialog::NewL();
+        dialog->PrepareLC( R_COD_UI_CONFIRM_NOTE );
+        HBufC* prompt;
+        if ( aData.iRiAlias )
+            {
+            // "Registration with %U needed. Register phone?"
+            HBufC* riAlias16 = CodUtil::ConvertLC( *aData.iRiAlias );
+            prompt = StringLoader::LoadL
+                ( R_QTN_DRM_QUERY_REGISTER_WITH_U, *riAlias16, iCoeEnv );
+            CleanupStack::PopAndDestroy( riAlias16 );
+            CleanupStack::PushL( prompt );
+            }
+        else
+            {
+            // "Registration with content provider needed. Register phone?"
+            prompt = StringLoader::LoadLC
+                ( R_QTN_DRM_QUERY_REGISTER_WITH_CP, iCoeEnv );
+            }
+        dialog->SetPromptL( *prompt );
+        CleanupStack::PopAndDestroy( prompt );
+        if ( !dialog->RunLD() ) 
+            {
+            CLOG(( 4, _L("  cancelled") ));
+            User::Leave( KErrCancel );
+            }
+        }
+    // Update the wait note with ROAP-specific text.
+    TInt resId = 0;
+    switch ( aData.iType )
+        {
+        case Roap::ERegistrationTrigger:
+            {
+            resId = R_QTN_DRM_WAIT_REGISTERING_DEVICE;
+            break;
+            }
+        case Roap::ERoAcquisitionTrigger:
+            {
+            resId = R_QTN_DRM_WAIT_GETTING_KEY;
+            break;
+            }
+        case Roap::EJoinDomainTrigger:
+            {
+            if ( aData.iDomainOperation == Roap::EJoinDomainOperation )
+                {
+                resId = R_QTN_DRM_WAIT_JOINING_DOMAIN;
+                }
+            else
+                {
+                resId = R_QTN_DRM_WAIT_UPDATING_ACCOUNT;
+                }
+            break;
+            }
+        case Roap::ELeaveDomainTrigger:
+            {
+            resId = R_QTN_DRM_WAIT_REMOVE_FR_ACCOUNT;
+            break;
+            }
+        default:
+            {
+            User::Leave( KErrNotSupported );
+            break;
+            }
+        }
+    __ASSERT_DEBUG( resId, CodUiPanic( ECodUiInternal ) );
+    TBool newNote( EFalse );
+    if ( !iWaitNote )
+        {
+        iWaitNote = new (ELeave) CCodWaitDialog
+            ( REINTERPRET_CAST( CEikDialog**, &iWaitNote ), *this );
+        iWaitNote->PrepareLC( R_COD_UI_WAIT_NOTE );
+        }
+    iWaitNote->SetTextL( resId );
+    if ( newNote )
+        {
+        iWaitNote->RunLD();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::RoapTriggerParsedL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleDialogCommandL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::HandleDialogCommandL( TInt aCommand )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::HandleDialogCommandL aCommand(%d)"), \
+        aCommand ));
+    HandleCommandL( aCommand );
+    CLOG(( 2, _L("<- CCodAppUi::HandleDialogCommandL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::HandleServerAppExit()
+// ----------------------------------------------------------
+//
+void CCodAppUi::HandleServerAppExit( TInt /*aReason*/ )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::HandleServerAppExit") ));
+    TRAP_IGNORE( ActivateNextUrlL() );
+    RunAppShutter();
+    CLOG(( 2, _L("<- CCodAppUi::HandleServerAppExit") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::OpenFileDoneL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::OpenFileDoneL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::OpenFileDoneL") ));
+    if ( iError )
+        {
+        LoadDoneL();
+        }
+    else
+        {
+        HandleModelChangeL();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::OpenFileDoneL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::StaticLoadDone()
+// ----------------------------------------------------------
+//
+TInt CCodAppUi::StaticLoadDone( TAny* aPtr )
+    {
+    STATIC_CAST( CCodAppUi*, aPtr )->LoadDone();
+    return EFalse;  // TCallback should return EFalse as TInt.
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::LoadDone()
+// ----------------------------------------------------------
+//
+void CCodAppUi::LoadDone()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::LoadDone") ));
+    iError = iCallback->iStatus.Int();
+    TRAPD( err, LoadDoneL() );
+    if ( err )
+        {
+        RunAppShutter();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::LoadDone") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::LoadDoneL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::LoadDoneL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::LoadDoneL iError(%d)"), iError ));
+    TBool exitApp( ETrue );
+    if ( CodDocument()->Model().GetPath().Length() )
+        {
+        // ROAP involved loading a file, treat as download and not as ROAP.
+        iRoap = EFalse;
+        }
+    // No service flow for Cancel or Reject.
+    if ( iError != KErrCancel && iError != KErrAbort )
+        {
+        if ( iRoap )
+            {
+            if ( iError )
+                {
+                exitApp = RoapFailedL();
+                }
+            else
+                {
+                exitApp = RoapOkL();
+                }
+            }
+        else
+            {
+            if ( iError )
+                {
+                exitApp = LoadFailedL();
+                }
+            else
+                {
+                exitApp = LoadOkL();
+                }
+            }
+        if ( exitApp )
+            {
+            ActivateNextUrlL();
+            }
+        }
+    if ( exitApp )
+        {
+        RunAppShutter();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::LoadDoneL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::LoadOkL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::LoadOkL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::LoadOkL") ));
+    __ASSERT_DEBUG( !iRoap, CodUiPanic( ECodUiInternal ) );
+    __ASSERT_DEBUG( !iError, CodUiPanic( ECodUiInternal ) );
+    TBool exitApp( ETrue ); // Exit by default.
+    // Show "File saved to..." note.
+    TUid handler = CodDocument()->Model().GetHandler();
+    RApaLsSession apaLsSess;
+    User::LeaveIfError( apaLsSess.Connect() );
+    CleanupClosePushL<RApaLsSession>( apaLsSess );
+    TApaAppInfo appInfo;
+    User::LeaveIfError( apaLsSess.GetAppInfo( appInfo, handler ) );
+    CleanupStack::PopAndDestroy();  // apaLsSess 
+    HBufC* prompt = StringLoader::LoadLC
+        ( R_QTN_FLDR_FILE_SAVED_TO, appInfo.iCaption, iCoeEnv );
+    CodDialog::ConfNoteL( *prompt );
+    CleanupStack::PopAndDestroy( prompt );
+    // Launch content, if applicable (DD or 'local' COD).
+    if ( !iCod || !CodDocument()->Model().Data().NextUrl().Compare
+                                            ( KCodReservedWordLocal ) )
+        {
+        exitApp = LaunchContentL( CodDocument()->Model().GetPath(),
+                                CodDocument()->Model().GetType().Des8() );
+        }
+    CLOG(( 2, _L("<- CCodAppUi::LoadOkL (%d)"), exitApp ));
+    return exitApp;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::LoadFailedL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::LoadFailedL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::LoadFailedL") ));
+    __ASSERT_DEBUG( !iRoap, CodUiPanic( ECodUiInternal ) );
+    __ASSERT_DEBUG( iError, CodUiPanic( ECodUiInternal ) );
+    TInt resId = 0;
+    if ( iError == KErrCodNoAccessPoint )
+        {
+        // "No access point" error has the same status code as all connection
+        // related errors, but needs different note.
+        resId = R_QTN_CD_INFO_NO_VALID_AP;
+        }
+    else
+        {
+        // Investigating status code (which carries less information than the
+        // error code) is generally enough to get the correct note.
+        switch( CodDocument()->Model().GetStatusCode() )
+            {
+            case KHttp900Success:
+            case KHttp902UserCancelled:
+            case KHttp921UserAborted:
+                {
+                // No error note shown for user cancel.
+                // (Sanity code, we never get here for user Cancel.)
+                iError = KErrNone;
+                break;
+                }
+                
+            case KHttp910NoMemory:
+            case KHttp901InsufficientMemory:
+                {
+                resId = R_QTN_CD_INFO_NOT_ENOUGH_MEM;
+                break;
+                }
+
+            case KHttp903LossOfService:
+                {
+                // User Text Resolver to get "Connection timeout".
+                iError = KErrCodHttpNoResponse;
+                break;
+                }
+
+            case KHttp906InvalidDescriptor:
+                {
+                resId = R_QTN_CD_INFO_SYNTAX_ERR;
+                break;
+                }
+
+            case KHttp922DeviceAborted:
+            case KHttp952DeviceAborted:
+                {
+                resId = R_QTN_CD_INFO_UNKNOWN_TYPE;
+                break;
+                }
+
+            case KHttp905AttributeMismatch:
+            case KHttp923NonAcceptableContent:
+            case KHttp953NonAcceptableContent:
+                {
+                resId = R_QTN_CD_INFO_UNSUPP_MIME_TYPE;
+                break;
+                }
+
+            case KHttp924LoaderError:
+            case KHttp954LoaderError:
+            case KHttp951InvalidDdVersion:
+                {
+                resId = R_QTN_CD_INFO_GENERIC_ERROR;
+                break;
+                }
+
+            default:
+                {
+                __ASSERT_DEBUG
+                    ( EFalse, CodUiPanic( ECodUiUnknownStatus ) );
+                break;
+                }
+            }
+        }
+
+    if ( resId )
+        {
+        CodDialog::InfoNoteL( resId, *iCoeEnv );
+        }
+    else if ( iError )
+        {
+        TPtrC msg( iErrorUi->TextResolver().ResolveErrorString( iError ) );
+        CodDialog::InfoNoteL( msg );
+        }
+    CLOG(( 2, _L("<- CCodAppUi::LoadFailedL") ));
+    return ETrue;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::RoapOkL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::RoapOkL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::RoapOkL") ));
+    __ASSERT_DEBUG( iRoap, CodUiPanic( ECodUiInternal ) );
+    __ASSERT_DEBUG( !iError, CodUiPanic( ECodUiInternal ) );
+    TBool exitApp( ETrue );
+    const CRoapData* roapData = CodDocument()->Model().GetRoapData();
+    if ( roapData ) // Safety code.
+        {
+        switch( roapData->iType )
+            {
+            case Roap::ERegistrationTrigger:
+                {
+                CodDialog::ConfNoteL
+                    ( R_QTN_DRM_CONF_DEVICE_REGISTERED, *iCoeEnv );
+                break;
+                }
+            case Roap::ERoAcquisitionTrigger:
+                {
+                exitApp = RoAcqOkL();
+                break;
+                }
+            case Roap::EJoinDomainTrigger:
+                {
+                if ( roapData->iDomainOperation == Roap::EJoinDomainOperation )
+                    {
+                    CodDialog::ConfNoteL
+                        ( R_QTN_DRM_CONF_JOINED_TO_DOMAIN, *iCoeEnv );
+                    }
+                else
+                    {
+                    CodDialog::ConfNoteL
+                        ( R_QTN_DRM_CONF_ACCOUNT_UPDATED, *iCoeEnv );
+                    }
+                break;
+                }
+            case Roap::ELeaveDomainTrigger:
+                {
+                CodDialog::ConfNoteL
+                    ( R_QTN_DRM_INFO_REMOVE_FR_ACCOUNT, *iCoeEnv );
+                break;
+                }
+            default:
+                {
+                // We should never get here.
+                __ASSERT_DEBUG( EFalse, CodUiPanic( ECodUiInternal ) );
+                }
+            }
+        }
+    CLOG(( 2, _L("<- CCodAppUi::RoapOkL returns(%d)"), exitApp ));
+    return exitApp;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::RoAcqOkL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::RoAcqOkL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::RoAcqOkL") ));
+    const CRoapData* roapData = CodDocument()->Model().GetRoapData();
+    __ASSERT_DEBUG ( roapData, CodUiPanic( ECodUiInternal ) );
+    __ASSERT_DEBUG ( roapData->iType == \
+        Roap::ERoAcquisitionTrigger, CodUiPanic( ECodUiInternal ) );
+
+    TFileName name;    // Note, filename and extension only! Not full path.
+    TDataType type;
+    TUid appUid( TUid::Null() );
+    RFile f;
+    CleanupClosePushL<RFile>( f );
+    if ( !iSilentMode && !iSuppressLaunch && roapData->iContentIdList.Count() )
+        {
+        __ASSERT_DEBUG( !iFs.Handle(), CodUiPanic( ECodUiInternal ) );
+        User::LeaveIfError( iFs.Connect() );
+        User::LeaveIfError( iFs.ShareProtected() );
+        CDcfRep* dcfRep = CDcfRep::NewL();
+        CleanupStack::PushL( dcfRep );
+        // It is not specified what to do if we have more content ids.
+        // Best guess: open the first.
+        TPtrC8 cid( *(roapData->iContentIdList[0]) );
+        TRAPD( err, dcfRep->GetFileHandleL ( cid, f, iFs ) );
+        if ( !err && CodUtil::CanOpenL( f ) )
+            {
+            User::LeaveIfError( f.Name( name ) );
+            RApaLsSession apaLs;
+            User::LeaveIfError( apaLs.Connect() );
+            CleanupClosePushL<RApaLsSession>( apaLs );
+            User::LeaveIfError( apaLs.AppForDocument( f, appUid, type ) );
+            CleanupStack::PopAndDestroy();  // apaLs
+            }
+        CleanupStack::PopAndDestroy( dcfRep );
+        }
+
+    TBool exitApp( ETrue );
+    if ( appUid.iUid )
+        {
+        // MO (related to the received RO) is already here and is supported
+        // by the system. Ask user if he wants to open it now.
+        __ASSERT_DEBUG( iFs.Handle(), CodUiPanic( ECodUiInternal ) );
+        __ASSERT_DEBUG( f.SubSessionHandle(), CodUiPanic( ECodUiInternal ) );
+        __ASSERT_DEBUG( name.Length(), CodUiPanic( ECodUiInternal ) );
+        CAknQueryDialog* dialog = CAknQueryDialog::NewL();
+        dialog->PrepareLC( R_COD_UI_CONFIRM_NOTE );
+        HBufC* prompt = StringLoader::LoadLC
+            ( R_QTN_DRM_QUERY_KEY_RECEIVED_OPEN, name, iEikonEnv );
+        dialog->SetPromptL( *prompt );
+        CleanupStack::PopAndDestroy( prompt );
+        if ( dialog->RunLD() ) 
+            {
+            __ASSERT_DEBUG( !iDocHandler, CodUiPanic( ECodUiInternal ) );
+            __ASSERT_DEBUG( !iDocParams, CodUiPanic( ECodUiInternal ) );
+            iDocHandler = CDocumentHandler::NewL();
+            iDocHandler->SetExitObserver( this );
+            iDocParams = CAiwGenericParamList::NewL();
+            User::LeaveIfError
+                ( iDocHandler->OpenFileEmbeddedL( f, type, *iDocParams ) );
+            exitApp = EFalse;
+            }
+        }
+    else
+        {
+        CodDialog::ConfNoteL( R_QTN_DRM_INFO_ACT_KEY_RECEIVED, *iCoeEnv );
+        }
+    CleanupStack::PopAndDestroy( &f );
+    CLOG(( 2, _L("<- CCodAppUi::RoAcqOkL returns(%d)"), exitApp ));
+    return exitApp;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::RoapFailedL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::RoapFailedL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::RoapFailedL iError(%d)"), iError ));
+    __ASSERT_DEBUG( iRoap, CodUiPanic( ECodUiInternal ) );
+    __ASSERT_DEBUG( iError, CodUiPanic( ECodUiInternal ) );
+    TBool exitApp( ETrue );
+    TInt resId = 0;
+    const CRoapData* roapData = CodDocument()->Model().GetRoapData();
+    if ( roapData ) // Safety code
+        {
+        // Some errors need specific message.
+        switch ( iError )
+            {
+            case KErrRoapDomainFull:
+                {
+                resId = R_QTN_DRM_INFO_ACCOUNT_IS_FULL;
+                break;
+                }
+            case KErrRoapInvalidDomain:
+                {
+                resId = R_QTN_DRM_ACCOUNT_NOT_RECOGNISED;
+                break;
+                }
+            case KErrRoapServer:
+                {
+                // Temporary server error. For RoAcq, offer retry; for other
+                // ROAP-s, fall through to default handling (plain error note).
+                if ( roapData->iType == Roap::ERoAcquisitionTrigger )
+                    {
+                    CAknQueryDialog* dialog = CAknQueryDialog::NewL();
+                    dialog->PrepareLC( R_COD_UI_CONFIRM_NOTE );
+                    HBufC* prompt = StringLoader::LoadLC
+                        ( R_QTN_DRM_GET_KEY_FAILED_RETRY, iEikonEnv );
+                    dialog->SetPromptL( *prompt );
+                    CleanupStack::PopAndDestroy( prompt );
+                    if ( dialog->RunLD() ) 
+                        {
+                        HandleCommandL( ECodUiCmdAccept );
+                        exitApp = EFalse;
+                        }
+                    break;
+                    }
+                // Not RoAcq: fall through to default (error note).
+                }
+            default:
+                {
+                // Default error message is based on trigger type.
+                switch ( roapData->iType )
+                    {
+                    case Roap::ERegistrationTrigger:
+                        {
+                        resId = R_QTN_DRM_INFO_DEVICE_REGIST_FAIL;
+                        break;
+                        }
+                    case Roap::ERoAcquisitionTrigger:
+                        {
+                        resId = R_QTN_DRM_INFO_GETTING_KEY_FAILED;
+                        break;
+                        }
+                    case Roap::EJoinDomainTrigger:
+                        {
+                        if ( roapData->iDomainOperation ==
+                             Roap::EJoinDomainOperation )
+                            {
+                            resId = R_QTN_DRM_INFO_REGISTRATION_FAILED;
+                            }
+                        else
+                            {
+                            resId = R_QTN_DRM_INFO_UPDATE_DOMAIN_FAIL;
+                            }
+                        break;
+                        }
+                    case Roap::ELeaveDomainTrigger:
+                        {
+                        resId = R_QTN_DRM_REMOVE_FR_ACCOUNT_FAIL;
+                        break;
+                        }
+                    default:
+                        {
+                        __ASSERT_DEBUG( EFalse, \
+                            CodUiPanic( ECodUiInternal ) );
+                        }
+                    }
+                break;
+                }
+            }
+        if( resId )
+            {
+            CodDialog::InfoNoteL( resId, *iCoeEnv );
+            }
+        }
+    CLOG(( 2, _L("<- CCodAppUi::RoapFailedL returns(%d)"), exitApp ));
+    return exitApp;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::LaunchContentL()
+// ----------------------------------------------------------
+//
+TBool CCodAppUi::LaunchContentL( const TDesC& aFname, const TDesC8& aType )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::LaunchContentL") ));
+    CLOG(( 3, _L("  aFile==<%S>"), &aFname ));
+    CLOG(( 3, _L8("  aType==<%S>"), &aType ));
+    TBool exitApp( ETrue ); // Exit by default.
+    if ( !iSilentMode &&
+         !iSuppressLaunch &&
+         aFname.Length() &&
+         CodUtil::CanOpenL( aFname )
+       )
+        {
+        __ASSERT_DEBUG( !iDocHandler, CodUiPanic( ECodUiInternal ) );
+        __ASSERT_DEBUG( !iDocParams, CodUiPanic( ECodUiInternal ) );
+        iDocHandler = CDocumentHandler::NewL();
+        iDocHandler->SetExitObserver( this );
+        iDocParams = CAiwGenericParamList::NewL();
+        // Need to copy argument; DocHandler takes non-const TDataType :-(
+        TDataType type( aType );
+        __ASSERT_DEBUG( !iFs.Handle(), CodUiPanic( ECodUiInternal ) );
+        User::LeaveIfError( iFs.Connect() );
+        User::LeaveIfError( iFs.ShareProtected() );
+        RFile f;
+        CleanupClosePushL<RFile>( f );
+        User::LeaveIfError( f.Open( iFs, aFname, EFileShareReadersOnly ) );
+        User::LeaveIfError
+            ( iDocHandler->OpenFileEmbeddedL( f, type, *iDocParams ) );
+        CleanupStack::PopAndDestroy( &f );
+        exitApp = EFalse;
+        }
+    CLOG(( 2, _L("<- CCodAppUi::LaunchContentL (%d)"), exitApp ));
+    return exitApp;
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::ActivateNextUrlL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::ActivateNextUrlL()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::ActivateNextUrlL") ));
+    TPtrC8 url;
+    TBool back( EFalse );
+
+    if ( iSilentMode || iSuppressNextUrl )
+        {
+        CLOG(( 2, _L("<- CCodAppUi::ActivateNextUrlL (off)") ));
+        return;
+        }
+
+    const CCodData& data = CodDocument()->Model().Data();
+    
+    if( iCod )
+        {
+        // This is a COD: choose between Next-URL or Next_URLatError.
+        if ( CodDocument()->Model().GetStatusCode() == KHttp900Success )
+            {
+            url.Set( data.NextUrl() );
+            }
+        else
+            {
+            url.Set( data.NextUrlAtError() );
+            }
+        // Recognize 'back' or 'local'.
+        if ( url.Length() )
+            {
+            if ( !url.Compare( KCodReservedWordLocal ) )
+                {
+                // 'local' -> no URL to launch.
+                url.Set( KNullDesC8 );
+                }
+            else if ( !url.Compare( KCodReservedWordBack ) )
+                {
+                // 'back' -> no URL to launch.
+                url.Set( KNullDesC8 );
+                back = ETrue;
+                }
+            }
+        }
+    else
+        {
+        // This is a DD: NextURL goes for success and failure.
+        url.Set( data.NextUrl() );
+        }
+            
+    CLOG(( 2, _L8("  url<%S> back(%d)"), &url, back ));
+
+    if ( url.Length() || back )
+        {
+        HBufC8* msg;
+        if ( url.Length() )
+            {
+            // Activate URL in Browser.
+            HBufC8* absUrl = CodUtil::AbsoluteUrlLC( data.SourceUri(), url );
+            msg = HBufC8::NewL
+                ( ((TDesC)KCodMsgLaunchBrowserWithUrl).Length() +
+                  absUrl->Length() );   // Not pushed, no leaving calls...
+            msg->Des().Append( KCodMsgLaunchBrowserWithUrl );
+            msg->Des().Append( *absUrl );
+            CleanupStack::PopAndDestroy( absUrl );
+            CleanupStack::PushL( msg ); // ...until this point!
+            }
+        else
+            {
+            // Empty URL (back), activate Browser.
+            msg = HBufC8::NewLC( 0 );
+            }
+
+        TApaTaskList taskList( iCoeEnv->WsSession() );
+        TApaTask task = taskList.FindApp( TUid::Uid( KCodWmlBrowserUid ) );
+        if ( task.Exists() )
+            {
+            // Browser is already running, send a message to it.
+            // (If not running, we don't launch it.)
+            task.SendMessage( TUid::Uid( 0 ), *msg );
+            }
+
+        CleanupStack::PopAndDestroy( msg );
+        }
+    CLOG(( 2, _L("<- CCodAppUi::ActivateNextUrlL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::SetCbaL()
+// ----------------------------------------------------------
+//
+void CCodAppUi::SetCbaL( TInt aCommandSetResourceId )
+    {
+    CLOG(( 2, _L("-> CCodAppUi::SetCbaL aCommandSetResourceId(%d)"), \
+        aCommandSetResourceId ));
+    CEikButtonGroupContainer* cba = Cba();
+    if ( cba )
+        {
+        cba->SetCommandSetL( aCommandSetResourceId );
+        iCurrentCba = aCommandSetResourceId;
+        cba->DrawNow();
+        }
+    CLOG(( 2, _L("<- CCodAppUi::SetCbaL") ));
+    }
+
+// ----------------------------------------------------------
+// CCodAppUi::PdPlayAvailable()
+// ----------------------------------------------------------
+//
+void CCodAppUi::PdPlayAvailable()
+    {
+    CLOG(( 2, _L("-> CCodAppUi::PdPlayAvailable") ));
+
+    CLOG(( 2, _L("<- CCodAppUi::PdPlayAvailable") ));
+    }