/** 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