diff -r 000000000000 -r 3ce708148e4d pnpmobileservices/pnpms/PnP/PnpProvisioningAppSrc/PnpProvisioningAppUi.cpp --- /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 +#include +#include +#include +#include +#include +#include // for KCRUidBrowser +#include // for CAknGlobalNote +#include // 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