pnpmobileservices/pnpms/PnP/PnpProvisioningAppSrc/PnpProvisioningAppUi.cpp
changeset 0 3ce708148e4d
child 2 a5fecba4b1e4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pnpmobileservices/pnpms/PnP/PnpProvisioningAppSrc/PnpProvisioningAppUi.cpp	Thu Dec 17 08:40:12 2009 +0200
@@ -0,0 +1,640 @@
+/*
+* Copyright (c) 2004-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: Implementation of PnPMS components
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <avkon.hrh>
+#include <apgcli.h>
+#include <textresolver.h>
+#include <rconnmon.h>
+#include <ApUtils.h>
+#include <PnpProvisioning.rsg>
+#include <BrowserUiSDKCRKeys.h>         // for KCRUidBrowser
+#include <AknGlobalNote.h>              // for CAknGlobalNote
+#include <AknGlobalConfirmationQuery.h> // for CAknGlobalConfirmationQuery
+
+#include "PnpProvisioningApp.h"
+#include "PnpProvisioningAppUi.h"
+#include "PnpProvisioningDocument.h"
+#include "pnpprovisioning.hrh"
+#include "PnpLogger.h"
+#include "cwaitdialogmonitor.h"
+
+
+_LIT( KQuestionMark, "?" );
+_LIT( KAmpersand, "&" );
+_LIT( KStatus, "Status=" );
+_LIT( KSpace, " " );
+
+const TUint KCallbackDelay = 1000000;
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+//
+// ----------------------------------------------------------
+// CPnpProvisioningAppUi::ConstructL()
+// 
+// ----------------------------------------------------------
+//
+void CPnpProvisioningAppUi::ConstructL()
+    {
+    LOGSTRING( "CPnpProvisioningAppUi::ConstructL" );
+    BaseConstructL( ENoScreenFurniture );
+    //send to backround
+    TApaTaskList taskList( CEikonEnv::Static()->WsSession() );
+    TApaTask task = taskList.FindApp( KUidPnpProvisioning );
+    task.SendToBackground();
+    this->StatusPane()->MakeVisible( EFalse );
+    HideApplicationFromFSW();
+    
+    CEikonEnv::Static()->AddForegroundObserverL( *this );
+    
+    // if service activation enabled allow automatic settings configuration instead
+    // of showing confirmation notes
+
+    TBool activationenabled = ServiceActivationEnabledL();
+    
+    if(!activationenabled)
+    {
+    HBufC* msgConfirmSave = CEikonEnv::Static()->AllocReadResourceLC(
+            R_TEXT_QUERY); 
+            
+        CAknGlobalConfirmationQuery* query = CAknGlobalConfirmationQuery::NewL();
+        CleanupStack::PushL( query );
+        TRequestStatus statusSave;
+        query->ShowConfirmationQueryL(
+            statusSave, 
+            *msgConfirmSave, 
+            R_AVKON_SOFTKEYS_YES_NO__YES,
+            R_QGN_NOTE_QUERY_ANIM);
+            
+        User::WaitForRequest( statusSave );
+        CleanupStack::PopAndDestroy( 2 );
+        
+        if( statusSave != EAknSoftkeyYes )
+            {
+            LOGSTRING("User rejected");
+            Exit();
+            }
+    }
+    ResolveApL( iApInUse );
+    
+    ShowWaitNoteL();
+
+    iPeriodic = CPeriodic::NewL( CActive::EPriorityStandard  );
+    iPeriodic->Start( KCallbackDelay, KCallbackDelay, TCallBack(CPnpProvisioningAppUi::PeriodicCallback, this) );
+    LOGSTRING( "CPnpProvisioningAppUi::ConstructL - done" );
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::~CPnpProvisioningAppUi()
+// Destructor
+// Frees reserved resources
+// ----------------------------------------------------
+//
+CPnpProvisioningAppUi::~CPnpProvisioningAppUi()
+    {
+    LOGSTRING( "~CPnpProvisioningAppUi" );
+
+    // iPeriodic is deleted in the document's destructor
+    if( iPeriodic )
+        {
+        iPeriodic->Cancel();
+        delete iPeriodic;
+        }
+    if (iDoorObserver)
+        {
+        LOGSTRING( "calling iDoorObserver->NotifyExit" );
+        iDoorObserver->NotifyExit(MApaEmbeddedDocObserver::ENoChanges);
+        }
+        
+    if( iGlobalWaitNote )
+        {
+        delete iGlobalWaitNote;
+        }
+        
+    if( iWaitDialogMonitor )
+        {
+        iWaitDialogMonitor->Cancel();
+        delete iWaitDialogMonitor;
+        }
+    LOGSTRING( "~CPnpProvisioningAppUi done" );
+   }
+
+// ------------------------------------------------------------------------------
+// CPnpProvisioningAppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
+//  This function is called by the EIKON framework just before it displays
+//  a menu pane. Its default implementation is empty, and by overriding it,
+//  the application can set the state of menu items dynamically according
+//  to the state of application data.
+// ------------------------------------------------------------------------------
+//
+void CPnpProvisioningAppUi::DynInitMenuPaneL(
+    TInt /*aResourceId*/,CEikMenuPane* /*aMenuPane*/)
+    {
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::HandleKeyEventL(
+//     const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
+// takes care of key event handling
+// ----------------------------------------------------
+//
+TKeyResponse CPnpProvisioningAppUi::HandleKeyEventL(
+    const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)
+    {
+    return EKeyWasNotConsumed;
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::HandleCommandL(TInt aCommand)
+// takes care of command handling
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::HandleCommandL(TInt aCommand)
+    {
+    switch ( aCommand )
+        {
+        case EAknSoftkeyBack:
+        case EEikCmdExit:
+            {
+            Exit();
+            break;
+            }
+
+        default:
+            break;      
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CPnpProvisioningAppUi::HandleGainingForeground
+//
+// -----------------------------------------------------------------------------
+//
+void CPnpProvisioningAppUi::HandleGainingForeground()
+    {
+    LOGSTRING( "CPnpProvisioningAppUi::HandleGainingForeground" );
+    TApaTaskList taskList( CEikonEnv::Static()->WsSession() );
+    TApaTask task = taskList.FindApp( KUidPnpProvisioning );
+    if( task.Exists() )
+        {
+        task.SendToBackground();
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CPnpProvisioningAppUi::HandleLosingForeground
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPnpProvisioningAppUi::HandleLosingForeground()
+    {
+    LOGSTRING( "CPnpProvisioningAppUi::HandleLosingForeground" );
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::RedirectL
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::RedirectL( const TDesC& aUrl, THttpProvStates::TProvisioningStatus  aStatus )
+    {
+    // do the redirect thing
+    LOGSTRING( "RedirectL" );
+
+    // Parameters are separated by space
+    // 1st parameter: type of the further parameters
+    // 2nd parameter: URL or  the uid of bookmark/saved deck/pushed deck.
+    // 3rd parameter: Access point Uid (in decimal format).
+    // the 3rd parameter is optional, and only for specifying AP for URL-s
+
+    HBufC* param = HBufC::NewLC( 300 );
+    TPtr paramPtr = param->Des();
+    paramPtr.Copy( _L( "4 " ) );
+    
+    
+    paramPtr.Append( aUrl );
+
+    // Assume there might already be parameters in the URL given
+    if( aUrl.Find( KQuestionMark ) != KErrNotFound )
+        {
+        paramPtr.Append( KAmpersand );
+        }
+    else
+        {
+        paramPtr.Append( KQuestionMark );
+        }
+
+    paramPtr.Append( KStatus );
+    paramPtr.AppendNum( (TInt) aStatus );
+
+    // Only give a valid AP
+    if( iApInUse != 0 )
+        {
+        paramPtr.Append( KSpace );
+        paramPtr.AppendNumUC( iApInUse );
+        }
+
+#ifdef _DEBUG
+    LOGSTRING( "redirecting params:" );
+    for( TInt i(0); i < paramPtr.Length(); i += 128 )
+        {
+        LOGTEXT( paramPtr .Right( paramPtr .Length() - i ) );
+        }
+#endif
+
+    TApaTaskList taskList( CEikonEnv::Static()->WsSession() );
+    TApaTask task = taskList.FindApp( KCRUidBrowser );
+    if ( task.Exists() )
+        {
+        LOGSTRING( "redirecting browser" );
+        HBufC8* param8 = HBufC8::NewLC( param->Length() );
+        param8->Des().Append( *param );
+        task.SendMessage( TUid::Uid( 0 ), *param8 ); // Uid is not used
+        //task.BringToForeground();     
+        CleanupStack::PopAndDestroy( param8 );
+        }
+    else 
+        {
+        LOGSTRING( "Could not find browser" );
+        RApaLsSession   appArcSession;
+        User::LeaveIfError(appArcSession.Connect());    // connect to AppArc server
+        TThreadId id;
+        appArcSession.StartDocument( *param, KCRUidBrowser, id );
+        appArcSession.Close();
+        }
+    CleanupStack::PopAndDestroy( param ); // param
+    LOGSTRING( "calling Exit()" ); 
+    Exit();
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::ResolveApL
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::ResolveApL( TUint32& aAp )
+    {
+    LOGSTRING("Trying to get AP used");
+
+
+    // PnPProvisioning app might be started by browsing to a service using
+    // PAOS filter 
+    // -> OnlineSupport app that normally sets the AP to DB might not have been
+    // used. It is also possible that the AP that OnlineSupport app used has
+    // been removed.
+
+    // So we try to use the AP currently in use first; if none is in use read the AP
+    // from shared data / cenrep.
+
+    RConnectionMonitor connMon;
+    connMon.ConnectL();
+    CleanupClosePushL( connMon );
+    TUint connectionCount(0);
+    TRequestStatus status( KRequestPending );
+    connMon.GetConnectionCount( connectionCount, status );
+    // No user interaction possible at this point so no need to make the call asynchronously
+    User::WaitForRequest( status );
+    LOGSTRING("Trying to get AP used - 2");
+
+    for( TUint i(1); i <= connectionCount; i++ )
+        {
+        LOGSTRING("Trying to get AP used - 3");
+        TUint connectionId(0);
+        TUint subConnectionCount(0);
+        TInt err = connMon.GetConnectionInfo( i, connectionId, subConnectionCount );
+        if( err != KErrNone )
+            {
+            LOGSTRING2( "err %i", err );
+            }
+
+        LOGSTRING("Trying to get AP used - 4");
+        TUint ap(0);
+        TRequestStatus status2( KRequestPending );
+        connMon.GetUintAttribute( connectionId, 0, KIAPId, ap, status2 );
+        User::WaitForRequest( status2 );
+        if( status2.Int() != KErrNone )
+            {
+            LOGSTRING2( "err %i", status2.Int() );
+            }
+        LOGSTRING("Trying to get AP used - 5");
+        if( ap != 0 )
+            {
+            LOGSTRING2("Trying to get AP used - found: %i", ap );
+
+            CCommsDatabase* commDb = CCommsDatabase::NewL( EDatabaseTypeIAP );
+            CleanupStack::PushL( commDb );
+            CApUtils* utils = CApUtils::NewLC( *commDb );
+            //aAp = utils->WapIdFromIapIdL( ap );
+            LOGSTRING2( "wap id: %i", aAp );
+            
+            // In some cases the connection has to be reset after saving
+            // provisioned settings
+            TInt err = connMon.SetBoolAttribute( 0, 0, KConnectionStopAll, ETrue );
+            LOGSTRING2( "Connection stop error: %i", err );
+            CleanupStack::PopAndDestroy( utils );
+            CleanupStack::PopAndDestroy( commDb );
+            CleanupStack::PopAndDestroy(); // connMon.Close()
+            LOGSTRING("Trying to get AP used - done");
+            return;
+            }
+        }
+    CleanupStack::PopAndDestroy(); // connMon.Close()
+    }
+    
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::DoExit()
+// exits app.
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::DoExit()
+    {
+    LOGSTRING( "DoExit" );
+    Exit();
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::PeriodicCallback
+// ----------------------------------------------------
+//
+TInt CPnpProvisioningAppUi::PeriodicCallback( TAny* aPtr )
+    {
+    TRAPD( err, ( (CPnpProvisioningAppUi*)aPtr )->DoPeriodicCallbackL( aPtr ) );
+    if( err != KErrNone )
+        {
+        LOGSTRING2( "Error in DoPeriodicCallBackL: %i", err );
+        if( err == KLeaveExit )
+            User::Leave( KLeaveExit );
+        }
+    return KErrNone;
+    }
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::DoPeriodicCallbackL
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::DoPeriodicCallbackL( TAny* aPtr )
+    {
+    LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback" );
+
+    CPnpProvisioningAppUi* ui = (CPnpProvisioningAppUi*)aPtr;
+    CPnpProvisioningDocument* document = (CPnpProvisioningDocument*)ui->Document();
+    TInt leavestatus = KErrNone;
+    TInt noRedirect = 0;
+    THttpProvStates::TProvisioningStatus status = THttpProvStates::EStatusOk;
+
+    LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback - Is doc ready?" );
+
+    if( !(document->Ready()) )
+        {
+        LOGSTRING( "Document not ready yet" );
+        User::Leave( KErrNotReady );
+        }
+
+    ui->iPeriodic->Cancel();
+    // document->SetPeriodic( ui->iPeriodic );
+    TRAP( leavestatus, status = document->SaveSettingsL() );
+    if( leavestatus != KErrNone )
+        {
+        LOGSTRING2( "SaveSettingsL leave code: %i", leavestatus );
+        
+        if( leavestatus == THttpProvStates::EStatusRejected )
+            {
+            // user has cancelled
+            ui->DoExit();
+            }
+        else
+            {
+            ui->ShowErrorNoteL();
+            }
+        }
+
+    LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback - get report url" );
+
+    // try to get the redirect url
+    TBuf<512> url;
+    TRAPD( err, url.Copy( document->GetReportUrlL().Left(512) ) );
+    if( err != KErrNone )
+        {
+        LOGSTRING2( "no report url:%i", err );
+        
+        TerminateBrowserL(err, noRedirect);
+        
+        ui->DoExit();
+        }
+    else
+        {
+        if( status != THttpProvStates::EStatusOk )
+            {
+            LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback - do redirect" );
+            
+            TerminateBrowserL(KErrGeneral, noRedirect);
+            if(noRedirect == 1)
+            ui->DoExit();
+            ui->RedirectL( url, status );
+            }
+        else if( leavestatus != KErrNone )
+            {
+            LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback - do redirect with leave status" );
+            
+            TerminateBrowserL(leavestatus, noRedirect);
+            if(noRedirect == 1)
+            ui->DoExit();
+            
+            ui->RedirectL( url, THttpProvStates::TProvisioningStatus( leavestatus ) );
+            }
+        else
+            {
+            LOGSTRING2( "Provisioning status: %i", status );
+
+            // Since Plat sec there is no need to restart Browser after provisioning
+            // has been done.
+            // In some cases the connection has to be reset, though
+            // (it is done in ResolveApL)
+            LOGSTRING( "Making redirect" );
+            
+           //Before Making redirect check if application launched PNPMS.
+           //If application has not launched PNPMS client then do redirect
+           // otherwise call for Service Activation and launch choosen application
+           // closing browser
+           
+        
+          		TerminateBrowserL(KErrNone,noRedirect);
+          		
+	    		if(noRedirect == 1)
+            		  ui->DoExit();
+	    		
+            
+            ui->RedirectL( url, THttpProvStates::EStatusOk );
+            }
+        }
+
+    LOGSTRING( "CPnpProvisioningAppUi::PeriodicCallback - done" );
+    }
+    
+//// ----------------------------------------------------
+// CPnpProvisioningAppUi::ServiceActivationEnabled()
+// ----------------------------------------------------
+//
+TBool CPnpProvisioningAppUi::ServiceActivationEnabledL()
+{
+	CPnpProvUtil *provUtil = CPnpProvUtil::NewLC();
+	TUint32 uidval = 0;
+	TRAPD(err, uidval = provUtil->GetApplicationUidL());
+		              
+	CleanupStack::PopAndDestroy();    //provutil     
+
+	if(uidval && !err)
+        {
+	 	return ETrue;
+	}
+	
+	return EFalse;
+	
+}
+
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::TerminateBrowserIfErrorL()
+// ----------------------------------------------------
+//
+
+void CPnpProvisioningAppUi::TerminateBrowserL(TInt aError, TInt& aNoRedirect)
+{
+	    // Terminate browser and launch choosen application based on status of
+      // aNoRedirect status
+      // If error status is KErrNone  the application is launched closing browser
+      // If there are errors then terminate browser without launching application
+	
+	    	CPnpProvUtil *provUtil = CPnpProvUtil::NewLC();
+        CPnpServiceActivation *serviceActivate = CPnpServiceActivation::NewLC();
+    		TUint32 uidval = 0;
+		
+				TRAPD(err, uidval = provUtil->GetApplicationUidL());
+                      
+        if(uidval && !err)
+        {
+            if(aError == KErrNone)
+            	TRAP_IGNORE(serviceActivate->LaunchApplicationL());
+          	
+          	TRAP_IGNORE(serviceActivate->KillBrowserL());
+						TRAP_IGNORE(provUtil -> SetApplicationUidL(0));
+			
+	   				// Interger value is required in case of handling multiple cases in redirection
+	   				// With current implementation only 2 values are supported 0 and 1
+	   				aNoRedirect = 1;	
+			
+			 	
+        }
+        
+        CleanupStack::PopAndDestroy(2);
+        
+        
+}
+
+
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::ShowErrorNoteL()
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::ShowErrorNoteL()
+    {
+    HBufC* msgTextSaved = CEikonEnv::Static()->
+            AllocReadResourceLC( R_TEXT_CANNOT_SAVE ); 
+
+    CAknGlobalNote* globalNote = CAknGlobalNote::NewL();
+    CleanupStack::PushL( globalNote );
+    globalNote->ShowNoteL( EAknGlobalErrorNote , *msgTextSaved );
+    CleanupStack::PopAndDestroy( 2 );
+    }
+    
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::ShowWaitNoteL()
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::ShowWaitNoteL()
+    {
+    HBufC* msgText = CEikonEnv::Static()->
+        AllocReadResourceLC( R_TEXT_WAIT_SAVING ); 
+
+    if (iWaitDialogMonitor)
+        {
+        iWaitDialogMonitor->Cancel();
+        delete iWaitDialogMonitor;
+        iWaitDialogMonitor = NULL;
+        }
+    // instantiate the active object CGlobalConfirmationObserver
+    iWaitDialogMonitor = CWaitDialogMonitor::NewL( *this );
+    
+    // SetActive
+    iWaitDialogMonitor->Start();
+    
+    if (!iGlobalWaitNote)
+        {
+        iGlobalWaitNote = CAknGlobalNote::NewL();
+        }
+
+     iGlobalWaitNote->SetSoftkeys( R_AVKON_SOFTKEYS_EMPTY);
+    iGlobalWaitNote->ShowNoteL(
+        iWaitDialogMonitor->iStatus,
+        EAknGlobalWaitNote,
+        *msgText );
+    
+    CleanupStack::PopAndDestroy( msgText );
+    }
+    
+// ----------------------------------------------------
+// CPnpProvisioningAppUi::WaitDialogDismissedL()
+// ----------------------------------------------------
+//
+void CPnpProvisioningAppUi::WaitDialogDismissedL( const TInt aStatusCode )
+    {
+    LOGSTRING2( "CPnpProvisioningAppUi::WaitDialogDismissedL aStatus is %i",aStatusCode );
+    LOGSTRING2( "iWaitDialogMonitor->iStatus is %i" , iWaitDialogMonitor->iStatus.Int() );
+    if( aStatusCode == EAknSoftkeyCancel || aStatusCode == EAknSoftkeyExit ||
+    			aStatusCode == KErrCancel ) //End key results in KErrCancel
+        {
+        // user cancelled
+        LOGSTRING( "CPnpProvisioningAppUi::WaitDialogDismissedL - user cancelled" );
+        Exit();
+        }
+//Handling End Key
+    if(aStatusCode == EAknSoftkeyEmpty && iWaitDialogMonitor->iStatus == KErrCancel )
+    	{
+    	LOGSTRING( "End key or User cancel done, but DOc tries to close instead of RunL of iWaitDialogMonitor " );
+    	//Exit();
+    	iWaitDialogMonitor->Cancel();
+    	User::Leave( THttpProvStates::EStatusRejected );
+    	}
+        
+    if( iGlobalWaitNote )
+        {
+        delete iGlobalWaitNote;
+        iGlobalWaitNote = NULL;
+        }
+        
+    if( iWaitDialogMonitor )
+        {
+        iWaitDialogMonitor->Cancel();
+        delete iWaitDialogMonitor;
+        iWaitDialogMonitor = NULL;
+        }
+    }
+
+// End of File