/*
* 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
const TInt KMimeTextLength = 64;
// -----------------------------------------------------------------------
// 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 = HBufC::NewL( KMimeTextLength );
TPtr iMimePtr = iMime->Des();
iMimePtr.Copy( SwiUI::KSisxMimeType );
// 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