apengine/apsettingshandlerui/src/apsettingsdeleteoperation.cpp
changeset 0 5a93021fdf25
child 8 2e6c4614c58e
child 23 7ec726f93df1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apengine/apsettingshandlerui/src/apsettingsdeleteoperation.cpp	Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,630 @@
+/*
+* Copyright (c) 2002 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 class CApSettingsDeleteOperation
+*
+*/
+
+
+// INCLUDE FILES
+#include <ApDataHandler.h>
+#include <ApUtils.h>
+#include <ActiveApDb.h>
+#include <ApSettingsHandlerCommons.h>
+#include <VpnApEngine.h>
+#include <AknWaitDialog.h>
+#include <AknProgressDialog.h>
+#include <cdbcols.h>
+#include <ErrorUI.h>
+#include "Apsettingsdeleteoperation.h"
+
+#include <WEPSecuritySettingsUI.h>
+#include <WPASecuritySettingsUI.h>
+#include <ApAccessPointItem.h>
+
+// Following includes are needed only for the test
+// when ALL APs are deleted (checking delays, etc.)
+// For testing purpose only, to make process time longer.
+//  TEST STARTS
+#include <ActiveApDb.h>
+#include <ApSelect.h>
+#include <ApListItem.h>
+#include "ApSelectorListBoxModel.h"
+#include "ApSettingsHandlerLogger.h"
+
+#include <ApSetUI.rsg>
+//  TEST ENDS
+
+
+// Stack size of the receiver thread.
+LOCAL_C const TInt KDeleteThreadStackSize = 40960;
+
+// Name of the receiver thread.
+_LIT( KDeleteThreadName, "Access Point Settings UI Delete Operation" );
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::NewL
+// ---------------------------------------------------------
+//
+CApSettingsDeleteOperation* CApSettingsDeleteOperation::NewL(
+                                TInt aNoteControlId,
+                                TInt aResourceID,
+                                TUint32 aUid,
+                                const TDesC& aNoteText
+                                )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::NewL")
+    
+    CApSettingsDeleteOperation* db =
+            new ( ELeave ) CApSettingsDeleteOperation(
+                            aNoteControlId,
+                            aResourceID,
+                            aUid
+                            );
+    CleanupStack::PushL( db );
+    db->ConstructL( aNoteText );
+    CleanupStack::Pop();
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::NewL")
+    return db;
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::ConstructL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::ConstructL( const TDesC& aNoteText )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::ConstructL")
+    
+    iErrorUi = CErrorUI::NewL( *CCoeEnv::Static() );
+    iNoteText = aNoteText.AllocL();
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::ConstructL")
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::CApSettingsDeleteOperation
+// ---------------------------------------------------------
+//
+CApSettingsDeleteOperation::CApSettingsDeleteOperation(
+                                 TInt aNoteControlId,
+                                 TInt aResourceID,
+                                 TUint32 aUid
+                                 )
+: CActive( EPriorityLow ),
+  iNoteControlId( aNoteControlId ),
+  iResourceID( aResourceID ),
+  iUid( aUid )
+    {
+    CActiveScheduler::Add(this);
+    APSETUILOGGER_WRITE( EModel,"Thread added to scheduler");
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::~CApSettingsDeleteOperation
+// ---------------------------------------------------------
+//
+CApSettingsDeleteOperation::~CApSettingsDeleteOperation()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::~CApSettingsDeleteOperation")
+    
+    if(iDeleteOperation.Handle() != 0)
+        {
+        // wait for deletion to finish
+        TRequestStatus status;          
+        iDeleteOperation.Logon(status);
+        User::WaitForRequest(status);
+        
+        iDeleteOperation.Close();
+        }
+        
+    Cancel();                        
+    
+    delete iWaitDialog;
+
+    delete iNoteText;
+    delete iErrorUi;
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::~CApSettingsDeleteOperation")
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::RunL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::RunL()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::RunL")
+    
+    switch ( iState )
+        {
+        case EProcOnDialogOn:
+            { // two chances :
+            // 1. Process finished normally
+            // 2. Process leaved with error
+            iState = EProcOffDialogOn;
+            if ( iWaitDialog )
+                {
+                iWaitDialog->ProcessFinishedL();
+                }
+            if ( iStatus.Int() != KErrNone )
+                {
+                // some error has occured
+                iErr = iStatus.Int();
+                }
+            Next();
+            break;
+            }
+        case EProcOffDialogOn:
+            {
+            // now we wait for the dialog to be dismissed
+            // just to be able to delete it
+            // stays in this state as long as DialogDismissedL()
+            // is not called, it will move it out into
+            // EProcOffDialogOff and it also deletes
+            Next();
+            break;
+            }
+        case EProcOnDialogOff:
+            { // this can't be, as dialog MUST stay as long as operation...
+            iState = EProcOffDialogOff;
+            Next();
+            break;
+            }
+        case EProcOffDialogOff:
+            { // now we can safely delete the dialog
+            if ( iWaitDialog )
+                {
+                delete iWaitDialog;
+                }
+            if ( iErr != KErrNone )
+                {
+                // some error has occured
+                iErrorUi->ShowGlobalErrorNoteL( iErr );
+                }
+            iDeleteOperation.Kill( iErr );
+            iDeleteOperation.Close();            
+//            delete this;
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EInvalidState ) );
+            break;
+            }
+        }
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::RunL")
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::DoCancel
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::DoCancel()
+    { // must be here as it is pure virtual in base...    
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::DoCancel")
+    
+    if (iDeleteOperation.Handle() != 0 && iStatus == KRequestPending)
+        {
+        iDeleteOperation.LogonCancel(iStatus);
+        } 
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::DoCancel")
+    }
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::DialogDismissedL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::DialogDismissedL( TInt /*aButtonId*/ )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::DialogDismissedL")
+    
+    switch ( iState )
+        {
+        case EProcOnDialogOn:
+            { // can't be, it means that dialog is dismissed by user
+            // but process is still runing...
+            iState = EProcOnDialogOff;
+            break;
+            }
+        case EProcOffDialogOn:
+            {
+            // set dialog off
+            iState = EProcOffDialogOff;
+            // as proc is already off, it circles in RunL,
+            break;
+            }
+        case EProcOnDialogOff:
+            { // can't be, it is already off...
+            iState = EProcOnDialogOff;
+            Next();
+            break;
+            }
+        case EProcOffDialogOff:
+            {// can't be, it is already off...
+            iState = EProcOffDialogOff;
+            Next();
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EInvalidState ) );
+            break;
+            }
+        }
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::DialogDismissedL")
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::StartL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::StartL()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::StartL")
+    
+    iStatus = KRequestPending;
+    // set the internal state as both is running
+    iState = EProcOnDialogOn;
+
+    // now we can start wait note...
+    StartWaitNoteL();
+
+    // now start new thread with operation
+    StartDeleteOperationThreadL();
+
+    SetActive();
+    // now we can wait on it...
+    // wait until the started thread completes (delete operation completes)
+    // and it will enter RunL. RunL will notify the wait dialog about the
+    // completion of the process.
+    // As the dialog shall wait ~0.5 sec till display AND must be visible
+    // for ~1.5 sec. as a minimum, but must stay up as long as the 'process'
+    // on it is waiting for does not completes, we have the following chances:
+    // if the process is shorter than 0.5,
+        // after operation completes, state moves to EProcOffDialogOn,
+        // dialog will be notified about completion by RunL, and RunL starts
+        // circle and wait for the dialog to finish, multiply re-entering
+        // and leaving RunL, as long as the state is EProcOffDialogOn.
+        // As time was shorter than 0.5, thus dialog will not show itself
+        // and will call DialogDismissedL, which will change the
+        // state to EProcOffDialogOff, which, on entering
+        // RunL again, will delete the dialog and kill the thread.
+    // if the process was longer than 0.5 but shorter than 0.5+1.5sec,
+        // after operation completes, state moves to EProcOffDialogOn,
+        // dialog will be notified about completion by RunL, and RunL starts
+        // circle and wait for the dialog to finish, multiply re-entering
+        // and leaving RunL, as long as the state is EProcOffDialogOn.
+        // As time was longer than 0.5, thus dialog will show itself
+        // and will stay up for 1.5 sec, as process ended between
+        // 0.5 and (0.5+1.5). After it dialog will call DialogDismissedL,
+        // which will change the state to EProcOffDialogOff, which, on
+        // entering RunL again, will delete the dialog and kill the thread.
+    // if the process was longer than 0.5+1.5
+        // after operation completes, state moves to EProcOffDialogOn,
+        // dialog will be notified about completion by RunL, and RunL starts
+        // circle and wait for the dialog to finish, multiply re-entering
+        // and leaving RunL, as long as the state is EProcOffDialogOn.
+        // As time was longer than 0.5+1.5, thus dialog will show itself
+        // and will stay up for as long as 'process/operation' is not finished.
+        // As thread completes, notifies dialog, after it dialog will
+        // call back DialogDismissedL, which will change the state
+        // to EProcOffDialogOff, which, on entering RunL again,
+        // will delete the dialog and kill the thread.
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::StartL")
+    }
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::Next
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::Next()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::Next")
+    
+    iStatus = KRequestPending;
+    SetActive();
+    TRequestStatus *status = &iStatus;
+    User::RequestComplete( status, KErrNone );  // Invoke RunL()
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::Next")
+    }
+
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::RunDeleteThread
+// ---------------------------------------------------------
+//
+TInt CApSettingsDeleteOperation::RunDeleteThread( TAny* aPtr )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::RunDeleteThread")
+    
+    CApSettingsDeleteOperation* aop = 
+            STATIC_CAST( CApSettingsDeleteOperation*, aPtr );
+
+
+    CTrapCleanup* TheTrapCleanup = CTrapCleanup::New(); // get cleanup stack
+
+    TRAPD(r, aop->DoRunDeleteThreadL( aop ) );
+
+    delete TheTrapCleanup; // destroy cleanup stack
+
+    aop->iErr = r;
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::RunDeleteThread")
+    return ( r );
+    }
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::DoRunDeleteThreadL
+// ---------------------------------------------------------
+//
+TInt CApSettingsDeleteOperation::DoRunDeleteThreadL( 
+                                    CApSettingsDeleteOperation* aop )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::DoRunDeleteThreadL")
+    
+    CCommsDatabase* db = CCommsDatabase::NewL( EDatabaseTypeIAP );
+    CleanupStack::PushL( db );
+    
+    APSETUILOGGER_WRITE( EDelete,"Commsdb created");
+
+    CApDataHandler* handler = CApDataHandler::NewLC( *db );
+    
+    APSETUILOGGER_WRITE( EDelete,"CApDataHandler created");
+    
+    CVpnApEngine* vpnengine = CVpnApEngine::NewLC( db );
+
+    APSETUILOGGER_WRITE( EDelete,"CVpnApEngine created");
+
+    TBool ownTransaction = StartTransactionLC( db, 
+                                               /*aWrite*/ETrue, 
+                                               /*aRetry*/ETrue );
+
+    APSETUILOGGER_WRITE( EDelete,"Tr.started");
+
+//  NORMAL OPERATION STARTS
+    TBool isvpn = vpnengine->IsVpnApL( aop->iUid );
+
+    APSETUILOGGER_WRITE( EDelete,"IsVpnApL returned");
+    
+    // if linked to a VPN, the VPN also must be deleted
+    // deleting the VPN part is the delete operation's responsibility...
+    if ( isvpn )
+        {
+        vpnengine->DeleteVpnL( aop->iUid );
+        }
+    else
+        {
+        handler->RemoveAPL( aop->iUid );
+        }
+    
+    APSETUILOGGER_WRITE( EDelete,"RemoveAPL returned");
+
+
+    if ( ownTransaction )
+        {
+        TInt err = db->CommitTransaction();
+        User::LeaveIfError( err );
+        CleanupStack::Pop(); // RollbackTransactionOnLeave
+        }
+
+    APSETUILOGGER_WRITE( EDelete," delete finished");
+
+    CleanupStack::PopAndDestroy( 3, db ); //db,handler,vpnengine
+
+//  NORMAL OPERATION ENDS
+
+
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::DoRunDeleteThreadL")
+    return KErrNone;
+    }
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::StartWaitNoteL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::StartWaitNoteL()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::StartWaitNoteL")
+    
+    if ( iWaitDialog )
+        {
+        delete iWaitDialog;
+        iWaitDialog = NULL;
+        }
+    iWaitDialog =
+        new ( ELeave ) CAknWaitDialog
+                ( REINTERPRET_CAST(CEikDialog**,&iWaitDialog) );
+    iWaitDialog->PrepareLC( iResourceID );
+    iWaitDialog->SetTone( CAknNoteDialog::ENoTone );
+    iWaitDialog->SetTextL( *iNoteText );
+    iWaitDialog->SetCallback( this );
+    iWaitDialog->RunLD();
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::StartWaitNoteL")
+    }
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::StartDeleteOperationThreadL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::StartDeleteOperationThreadL()
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::StartDeleteOperationThreadL")
+    
+    TInt err = iDeleteOperation.Create
+            (
+            KDeleteThreadName, // aName
+            RunDeleteThread, // aFunction
+            KDeleteThreadStackSize, // aStackSize
+            NULL,         // Use this heap.
+            this // aPtr
+            );
+    APSETUILOGGER_WRITE_FORMAT( EDelete, "iDeleteOperation create returned, code:%d", err);    
+    
+    User::LeaveIfError( err );
+    // on termination/death of this thread, it will call RunL
+    iDeleteOperation.Logon( iStatus );
+    // let's start the thread
+    iDeleteOperation.Resume();
+    // set the internal state as both is running
+    iState = EProcOnDialogOn;
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::StartDeleteOperationThreadL")
+    }
+
+
+
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::StarTransactionLC
+// ---------------------------------------------------------
+//
+TBool CApSettingsDeleteOperation::StartTransactionLC( CCommsDatabase* aDb,
+                                                      TBool aWrite, 
+                                                      TBool aRetry /*ETrue*/ )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::StartTransactionLC")
+    
+    TBool retval( EFalse );
+    if ( !aDb->InTransaction() )
+        {
+        TInt retriesLeft( aRetry ? KRetryCount : 1 );
+        TInt err = aDb->BeginTransaction();
+        while ( ( err == KErrLocked ) && --retriesLeft )
+            {
+            User::After( KRetryWait );
+            err = aDb->BeginTransaction();
+            if (aWrite )
+                {
+                TRAP_IGNORE( GetWriteLockL( aDb ) );
+                }
+            }
+        if ( err )
+            {
+            ShowNoteL( R_APUI_VIEW_TEXT_CANNOT_ACCESS_DB );
+            }
+        User::LeaveIfError( err );
+        CleanupStack::PushL( TCleanupItem( RollbackTransactionOnLeave, aDb ) );
+        retval = ETrue;
+        }
+    else
+        {
+        retval = EFalse;
+        }
+        
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::StartTransactionLC")
+    return retval;
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::GetWriteLockL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::GetWriteLockL( CCommsDatabase* aDb )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::GetWriteLockL")
+    
+    CCommsDbTableView* v = aDb->OpenTableLC( TPtrC(WAP_ACCESS_POINT ) );
+    TUint32 aDummyUid( KApNoneUID );
+    TInt err = v->InsertRecord( aDummyUid );
+    User::LeaveIfError( err );
+    v->CancelRecordChanges();
+    User::LeaveIfError( err );
+    CleanupStack::PopAndDestroy(); // v
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::GetWriteLockL")
+    }
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::RollbackTransactionOnLeave
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::RollbackTransactionOnLeave( TAny* aDb )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::RollbackTransactionOnLeave")
+    
+    CCommsDatabase* db = STATIC_CAST( CCommsDatabase*, aDb );
+    db->RollbackTransaction();
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::RollbackTransactionOnLeave")
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::ReadUintL
+// ---------------------------------------------------------
+//
+TInt CApSettingsDeleteOperation::ReadUintL( CCommsDbTableView* atable,
+                                            const TDesC& aColumn,
+                                            TUint32& aValue )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::ReadUintL")
+    
+    __ASSERT_DEBUG( (atable), Panic( ENullPointer ) ) ;
+    TRAPD( err, atable->ReadUintL( aColumn, aValue ) );
+    if ( err != KErrNone )
+        { // do not leave if readed value is not present in table...
+        if ( err != KErrUnknown )
+            User::Leave( err );
+        }
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::ReadUintL")
+    return err;
+    }
+
+
+// ---------------------------------------------------------
+// CApSettingsDeleteOperation::SetNoteTextL
+// ---------------------------------------------------------
+//
+void CApSettingsDeleteOperation::SetNoteTextL( const TDesC& aNoteText )
+    {
+    APSETUILOGGER_ENTERFN( EDelete,"DeleteOp::SetNoteTextL")
+    
+    delete iNoteText;
+    iNoteText = NULL; // must NULL it to satisfy CodeScanner...
+    iNoteText = aNoteText.AllocL();
+    
+    APSETUILOGGER_LEAVEFN( EDelete,"DeleteOp::SetNoteTextL")
+    }
+// End of File