diff -r 000000000000 -r ba25891c3a9e appinstaller/AppinstUi/Daemon/Src/uninstaller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/appinstaller/AppinstUi/Daemon/Src/uninstaller.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,372 @@ +/* +* 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 "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: +* +*/ + +#include "uninstaller.h" +#include "versionRevisor.h" +#include "SWInstDebug.h" + +#include "sisregistrysession.h" +#include "siscontents.h" +#include "sisparser.h" +#include "filesisdataprovider.h" + +#include "dessisdataprovider.h" +#include "siscontroller.h" +#include "sisinfo.h" +#include "sisuid.h" +#include "sisregistryentry.h" +#include "DialogWrapper.h" + +using namespace Swi; + +const static TInt KWaitTime = 3000000; // 2 secs + +// ----------------------------------------------------------------------- +// Two phased construction +// ----------------------------------------------------------------------- +// +CSisPkgUninstaller* CSisPkgUninstaller::NewL( + CProgramStatus& aMainStatus, + CVersionRevisor& aRevisor ) + { + CSisPkgUninstaller* self = new (ELeave) CSisPkgUninstaller(); + CleanupStack::PushL(self); + self->ConstructL( aMainStatus, aRevisor ); + CleanupStack::Pop(self); + return self; + } + + +// ----------------------------------------------------------------------- +// c++ constructor +// ----------------------------------------------------------------------- +// +CSisPkgUninstaller::CSisPkgUninstaller() : CActive( CActive::EPriorityStandard ) + { + CActiveScheduler::Add( this ); + } + + +// ----------------------------------------------------------------------- +// c++ destructor +// ----------------------------------------------------------------------- +// +CSisPkgUninstaller::~CSisPkgUninstaller() + { + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller start")); + + if ( EStateUninstalling == iProgramStatus->GetProgramStatus() ) + { + FLOG( _L("[SISUninstaller] Set status to idle")); + iProgramStatus->SetProgramStatusToIdle(); + } + + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: Cancel()")); + // Cancels the wait for completion of an outstanding request. + Cancel(); + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: Deque()")); + // Removes the active object from the active scheduler's list. + Deque(); + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: iTimer.Close()")); + iTimer.Close(); + iPkgUidArray.Close(); + delete iSilentUninstaller; + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: delete iMime")); + delete iMime; + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: delete iDialogs")); + delete iDialogs; + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: iApaSession.Close()")); + iApaSession.Close(); + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller: iFs.Close();")); + iFs.Close(); + + FLOG( _L("[SISUninstaller] ~CSisPkgUninstaller end")); + } + + +// ----------------------------------------------------------------------- +// 2nd phase construction +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::ConstructL( + CProgramStatus& aMainStatus, + CVersionRevisor& aRevisor ) + { + iProgramStatus = &aMainStatus; + iRevisor = &aRevisor; + User::LeaveIfError( iTimer.CreateLocal() ); + User::LeaveIfError( iFs.Connect() ); + User::LeaveIfError( iApaSession.Connect() ); + iFs.ShareProtected(); + iUidArrayIndex = 0; + iSilentUninstaller = NULL; + iState = EUninstallerStateIdle; + // Alloc descriptor for mime type sis/sisx + iMime = SwiUI::KSisxMimeType().AllocL(); + // Note this will create new instance for dialog class and + // also new dialog watcher AO for uninstaller. + // Since uninstaller is used rarely this is not big issue. + // In future dialog class could be added to CProgramStatus class + // member from where both installer and uninstaller could us it. + iDialogs = CDialogWrapper::NewL( iFs ); + } + + +// ----------------------------------------------------------------------- +// This function adds package uid to uninstall array. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::AddUidToListL( const TUid& aUID ) + { + iPkgUidArray.AppendL( aUID ); + } + + +// ----------------------------------------------------------------------- +// This function starts uninstall process. Leaves if nothing to do. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::StartUninstallL() + { + FLOG( _L("[SISUninstaller] StartUninstallL")); + + if( iPkgUidArray.Count() == 0 ) + { + FLOG( _L("[SISUninstaller] No UIDs leave uninstaller")); + User::Leave( KErrAbort ); + } + + // If daemon installer is in idle, start uninstall and + // set process status as uninstalling. + if ( EStateIdle == iProgramStatus->GetProgramStatus() ) + { + FLOG( _L("[SISUninstaller] StartUninstallL: Set EStateUninstalling") ); + iProgramStatus->SetProgramStatus( EStateUninstalling ); + } + + if ( iSilentUninstaller == NULL ) + { + FLOG( _L("[SISUninstaller] Create SilentUninstaller")); + iSilentUninstaller = CSilentUninstaller::NewL( iFs ); + } + + if ( iState == EUninstallerStateIdle ) + { + CompleteSelf(); + } + } + + +// ----------------------------------------------------------------------- +// Complete the request manually. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::CompleteSelf() + { + FLOG( _L("[SISUninstaller] CompleteSelf")); + + if ( !IsActive() ) + { + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + } + + +// ----------------------------------------------------------------------- +// Cancel the active request. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::DoCancel() + { + FLOG( _L("[SISUninstaller] DoCancel") ); + iTimer.Close(); + if ( iState == EUninstallerStateUninstalling ) + { + iSilentUninstaller->Cancel(); + } + } + + +// ----------------------------------------------------------------------- +// Handles the active object's request completion. Process the uninstall +// tasks and waits install process if needed. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::RunL() + { + FLOG_1( _L("[SISUninstaller] RunL: ProgramStatus = %d"), + iProgramStatus->GetProgramStatus() ); + + // If daemon installer is running let's wait some time and try again. + if ( EStateInstalling == iProgramStatus->GetProgramStatus() ) + { + FLOG( _L("[SISUninstaller] RunL: Wait daemon installer ! ! !") ); + TTimeIntervalMicroSeconds32 time( KWaitTime ); + iTimer.After( iStatus, time ); + SetActive(); + } + // Ok, run uninstaller. + else + { + FLOG( _L("[SISUninstaller] RunL: Start uninstalling process") ); + iProgramStatus->SetProgramStatus( EStateUninstalling ); + FLOG_1( _L("Daemon Uninstaller: RunL: SWI iStatus = %d"), + iStatus.Int()); + + switch ( iState ) + { + case EUninstallerStateUninstalling: + { + FLOG( _L("[SISUninstaller] RunL: EUninstallerStateUninstal.")); + // We are not checking SWI error status here because + // there is not need for that. If uninstall fails because + // some error, we can not fix it. In case of error we will + // start next uninstall. + + // Ok, server busy, we have to wait. + if ( iStatus.Int() == SwiUI::KSWInstErrBusy ) + { + FLOG(_L("[SISUninstaller] RunL: iStatus: KSWInstErrBusy")); + TTimeIntervalMicroSeconds32 time( KWaitTime ); + iTimer.After( iStatus, time ); + iState = EUninstallerStateBusy; + SetActive(); + break; + } + // Check if we have more to uninstall + else if ( iUidArrayIndex < iPkgUidArray.Count() ) + { + FLOG(_L("[SISUninstaller] RunL: Complete self and cont.")); + // Run again to kick of the next uninstallation. + iState = EUninstallerStateIdle; + CompleteSelf(); + } + // Ok all is done. + else + { + FLOG( _L("[SISUninstaller] RunL: Completed") ); + UninstallationCompleted( KErrNone ); + ExitUninstaller(); + } + } + break; + + case EUninstallerStateIdle: + { + FLOG( _L("[SISUninstaller] RunL: EDSisInstallerStateIdle") ); + // Check if there is pkgs to be uninstalled. + if ( iUidArrayIndex < iPkgUidArray.Count() ) + { + // Display installing note for user. + iDialogs->ShowWaitingNoteForUninstallerL(); + + FLOG_1( _L("[SISUninstaller] Run uninstall index = %d"), + iUidArrayIndex ); + + // Get next UID. + iUID = iPkgUidArray[ iUidArrayIndex ]; + // Increas pkg counter. + iUidArrayIndex++; + // Start uninstall process + iSilentUninstaller->UninstallL( iUID, iStatus, *iMime ); + //iDialogs->ShowWaitingNoteL(); + iState = EUninstallerStateUninstalling; + SetActive(); + } + else + { + // No more pkgs to uninstall. Let's quit. + FLOG( _L("[SISUninstaller] RunL: Completed") ); + UninstallationCompleted( KErrNone ); + ExitUninstaller(); + } + } + break; + + case EUninstallerStateBusy: + { + FLOG( _L("[SISUninstaller] RunL: EUninstallerStateBusy") ); + FLOG_1( _L("[SISUninstaller] Run uninstall again index = %d"), + iUidArrayIndex-1 ); + // Start uninstall process + iSilentUninstaller->UninstallL( iUID, iStatus, *iMime ); + iState = EUninstallerStateUninstalling; + SetActive(); + } + break; + + default: + FLOG(_L("[SISUninstaller] RunL: KErrNotSupported EXIT!!!")); + // This state is not supported, let's exit. + DoCancel(); + UninstallationCompleted( KErrNotSupported ); + ExitUninstaller(); + break; + } //switch case + } //if-else + } + + +// ----------------------------------------------------------------------- +// This function is called when RunL leaves. +// ----------------------------------------------------------------------- +// +TInt CSisPkgUninstaller::RunError( TInt aError ) + { + FLOG_1( _L("[SISUninstaller] RunError: error = %d"), aError ); + UninstallationCompleted( aError ); + return aError; + } + + +// ----------------------------------------------------------------------- +// This function is called after uninstall tasks are done. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::UninstallationCompleted( TInt /*aResult*/ ) + { + FLOG( _L("[SISUninstaller] UninstallationCompleted") ); + + if ( EStateUninstalling == iProgramStatus->GetProgramStatus() ) + { + FLOG( _L("[SISUninstaller] Set status to idle")); + iProgramStatus->SetProgramStatusToIdle(); + } + + iUidArrayIndex = 0; + iState = EUninstallerStateIdle; + + // Cancel waiting note. + TRAP_IGNORE( iDialogs->CancelWaitingNoteL() ); + } + + +// ----------------------------------------------------------------------- +// This is for self exit. +// ----------------------------------------------------------------------- +// +void CSisPkgUninstaller::ExitUninstaller() + { + FLOG( _L("[SISUninstaller] ExitUninstaller") ); + // Uninstall is completed and we do not need uninstaller anymore. + // Call revisor's destructor. + iRevisor->Exit(); + } + +//EOF