/*
* Copyright (c) 2007-2009 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: This module contains the implementation of CIAUpdateUiController
* class member functions.
*
*/
// INCLUDES
#include <avkon.hrh>
#include <StringLoader.h>
#include <centralrepository.h>
#include <AknUtils.h>
#include <SWInstDefs.h>
#include <avkon.rsg>
#include <featurecontrol.h>
#include <iaupdate.rsg>
#include <iaupdateparameters.h>
#include "iaupdateuicontroller.h"
#include "iaupdateuicontrollerobserver.h"
#include "iaupdateappui.h"
#include "iaupdate.hrh"
#include "iaupdatewaitdialog.h"
#include "iaupdateprogressdialog.h"
#include "iaupdatenode.h"
#include "iaupdatefwnode.h"
#include "iaupdatebasenode.h"
#include "iaupdatenodefilter.h"
#include "iaupdatefactory.h"
#include "iaupdatestarter.h"
#include "iaupdateprivatecrkeys.h"
#include "iaupdatecontrollerfile.h"
#include "iaupdateuiconfigdata.h"
#include "iaupdatedialogutil.h"
#include "iaupdateutils.h"
#include "iaupdateagreement.h"
#include "iaupdateautomaticcheck.h"
#include "iaupdateroaminghandler.h"
#include "iaupdatependingnodesfile.h"
#include "iaupdaterestartinfo.h"
#include "iaupdaterresultsfile.h"
#include "iaupdaterresult.h"
#include "iaupdateridentifier.h"
#include "iaupdateruids.h"
#include "iaupdaterdefs.h"
#include "iaupdatetools.h"
#include "iaupdateparametersfilemanager.h"
#include "iaupdateerrorcodes.h"
#include "iaupdatefileconsts.h"
#include "iaupdatefirsttimeinfo.h"
#include "iaupdaterefreshhandler.h"
#include "iaupdatedebug.h"
// cenrep in emulator:
// copy 2000F85A.txt to '\epoc32\release\winscw\udeb\Z\private\10202be9\'
// delete 2000F85A.txt from 'epoc32\winscw\c\private\10202be9\persists'
//
// cenrep in hardware:
// copy 2000F85A.txt to '\epoc32\data\Z\private\10202be9'
//
// This is a static function that is used with RPointerArray::Sort to sort
// the nodes according to their node depths and other special values.
TInt SortSelectedNodes( const MIAUpdateNode& aNode1, const MIAUpdateNode& aNode2 )
{
// Temporarily use the const_cast here to get the base node.
// After that, base node is set back to const. So, the casting here
// is safe to do.
const MIAUpdateBaseNode& baseNode1(
const_cast< MIAUpdateNode& >( aNode1 ).Base() );
const MIAUpdateBaseNode& baseNode2(
const_cast< MIAUpdateNode& >( aNode2 ).Base() );
if ( baseNode1.Uid().iUid == KIAUpdaterUid
&& baseNode2.Uid().iUid != KIAUpdaterUid )
{
// Self updater should always be the first one
// in the node array.
return -1;
}
else if ( baseNode2.Uid().iUid == KIAUpdaterUid
&& baseNode1.Uid().iUid != KIAUpdaterUid )
{
// Self updater should always be the first one
// in the node array.
return 1;
}
else if ( aNode1.IsSelfUpdate() && !aNode2.IsSelfUpdate() )
{
// Self updates always before normal nodes.
return -1;
}
else if ( !aNode1.IsSelfUpdate() && aNode2.IsSelfUpdate() )
{
// Self updates always before normal nodes.
return 1;
}
else
{
// The depth can be used in normal cases to make sure that dependency
// nodes are handled before their dependants. Notice, that this is
// a safe way even if dependency chain contains hidden nodes.
// The dependency nodes should be before its dependants in the array.
// The depth value informs how deep in the dependency hierarchy the node is.
// A depth value zero means that the node is a root. If multiple branches lead to
// a same node, then the greatest depth value is used for the node.
// The node can not ever depend on the node that has the same or greater depth.
TInt depthDiff( aNode2.Depth() - aNode1.Depth() );
if ( depthDiff != 0 )
{
// Depths were different.
// In some cases, the user may have chosen a dependency node only
// and left the dependant out. Then this node may be moved unnecessarily
// in the array. But because dependecies may change the selection order
// usually quite much, the possible unnecessary movement here should not
// matter. Notice, that using the depth values is really safe way to make
// sure the dependency nodes are handled before their dependants.
return depthDiff;
}
else
{
// Because depthDiffs equal we need to do some additional checking.
// This kind of comparison is also used in the filter.
// See: CIAUpdateNodeFilter::CompareAndMarkFilterNodes
TInt importanceDiff(
baseNode2.Importance() - baseNode1.Importance() );
if ( importanceDiff != 0 )
{
// Sort according to the importance because importances
// differ.
return importanceDiff;
}
else
{
// Because evertyhing else matched, we finally check
// the name. Items should be handled in alphabetical order
// now.
return baseNode1.Name().CompareC( baseNode2.Name() );
}
}
}
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CIAUpdateUiController* CIAUpdateUiController::NewLC(
MIAUpdateUiControllerObserver& aObserver )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewLC() begin");
CIAUpdateUiController* self =
new( ELeave ) CIAUpdateUiController( aObserver );
CleanupStack::PushL( self );
self->ConstructL();
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewLC() end");
return self;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CIAUpdateUiController* CIAUpdateUiController::NewL(
MIAUpdateUiControllerObserver& aObserver )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewL() begin");
CIAUpdateUiController* self =
CIAUpdateUiController::NewLC( aObserver );
CleanupStack::Pop( self );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::NewL() end");
return self;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::CIAUpdateUiController
// C++ constructor
// -----------------------------------------------------------------------------
//
CIAUpdateUiController::CIAUpdateUiController(
MIAUpdateUiControllerObserver& aObserver )
: iObserver( aObserver ),
iState( EIdle )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CIAUpdateUiController()");
iEikEnv = CEikonEnv::Static();
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::ConstructL
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::ConstructL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() begin");
iClosingAllowedByClient = ETrue;
iController =
IAUpdateFactory::CreateControllerL(
TUid::Uid( KIAUpdateFamilyUid ), *this );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 1");
iFilter = CIAUpdateNodeFilter::NewL();
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 2");
// Notice, this will read the init values from the file
// if the file exists. Otherwise, default values are used.
iControllerFile =
CIAUpdateControllerFile::NewL( IAUpdateFileConsts::KControllerFile );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() 3");
iConfigData = CIAUpdateUiConfigData::NewL();
iOffConfigurated = !IAUpdateEnabledL();
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConstructL() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::~CIAUpdateUiController
// Destructor
// -----------------------------------------------------------------------------
//
CIAUpdateUiController::~CIAUpdateUiController()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::~CIAUpdateUiController() begin");
CancelOperation();
delete iController;
iNodes.Reset();
iFwNodes.Reset();
iSelectedNodesArray.Reset();
iServicePackNodes.Reset();
delete iFilter;
delete iControllerFile;
delete iIdle;
delete iStarter;
delete iConfigData;
delete iRoamingHandler;
delete iParams;
delete iRefreshHandler;
delete iPreviousSelections;
// If dialogs have not been released yet, release them now.
// ProcessFinishedL() should normally be used for dialogs but
// here just use non-leaving delete. In normal cases, dialogs should
// already be released in the end of the update flow before coming here.
delete iWaitDialog;
delete iProgressDialog;
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::~CIAUpdateUiController() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::ConfigData
// Returns the configuration data from the config file.
// -----------------------------------------------------------------------------
//
const CIAUpdateUiConfigData& CIAUpdateUiController::ConfigData() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ConfigData()");
return *iConfigData;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::SetDefaultConnectionMethodL
// Sets the connection method for the update network connection.
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::SetDefaultConnectionMethodL( const TIAUpdateConnectionMethod& aMethod )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetDefaultConnectionMethodL() begin");
iController->SetDefaultConnectionMethodL( aMethod );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetDefaultConnectionMethodL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::CheckUpdatesL
// Updates the update item list.
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::CheckUpdatesL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesL() begin");
iCountOfAvailableUpdates = 0;
if ( iParams )
{
iFilter->SetFilterParams( iParams ); //iParams ownership is changed
iParams = NULL;
}
TBool agreementAccepted( EFalse );
CIAUpdateAgreement* agreement = CIAUpdateAgreement::NewLC();
agreementAccepted = agreement->AgreementAcceptedL();
if ( ( !agreementAccepted )&& ( iRequestType != IAUpdateUiDefines::ECheckUpdates ) )
{
// agreement (disclaimer) dialog is not prompted when CheckUpdates is called
//
// Refresh from network is allowed when first time case
iRefreshFromNetworkDenied = EFalse;
agreementAccepted = agreement->AcceptAgreementL();
}
CleanupStack::PopAndDestroy( agreement );
if ( !agreementAccepted )
{
if ( iRequestType == IAUpdateUiDefines::ECheckUpdates )
{
CIAUpdateAutomaticCheck* automaticCheck = CIAUpdateAutomaticCheck::NewLC();
TBool autoUpdateCheckEnabled = automaticCheck->AutoUpdateCheckEnabledL();
CleanupStack::PopAndDestroy( automaticCheck );
if ( !autoUpdateCheckEnabled )
{
iObserver.RefreshCompleteL( ETrue, KErrNone );
return;
}
}
else if ( iRequestType == IAUpdateUiDefines::EShowUpdates )
{
iObserver.UpdateCompleteL( KErrNone );
return;
}
else
{
CIAUpdateAppUi* appUi =
static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
appUi->Exit();
return;
}
}
if ( iRequestType == IAUpdateUiDefines::EShowUpdates && iRefreshed )
{
iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
iObserver.RefreshCompleteL( ETrue, KErrNone );
}
else
{
if ( IsStartedByLauncher() && AllowNetworkRefreshL() )
{
iUserRoamingRejection = iRoamingHandler->RoamingRejectionL();
}
TInt ret( iController->Startup() );
if ( ret == KErrAlreadyExists )
{
IAUPDATE_TRACE("[IAUPDATE] Controller startup already done.");
// Controller startup has already been done.
// So, no operation was started from the controller.
// So, call StartupComplete directly from here.
StartupComplete( KErrNone );
}
else
{
IAUPDATE_TRACE_1("[IAUPDATE] Controller startup error code: %d", ret);
// Something went wrong with controller startup if error code is not
// KErrNone here. Above, KErrAlreadyExists was handled separately.
// If ret is KErrInUse, then startup was still going on
// and new startup should not be called. Also, leave in that case.
User::LeaveIfError( ret );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartUpdateL
// Starts software updating
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::StartUpdateL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartUpdateL() begin");
// Just to be sure that self update related information
// is always in resetted state when new update flows are
// started.
iController->ResetSelfUpdate();
iUserRoamingRejection = iRoamingHandler->RoamingRejectionL();
if ( !iUserRoamingRejection )
{
CreateSelectedNodesArrayL();
if ( !IAUpdateUtils::SpaceAvailableInInternalDrivesL( iSelectedNodesArray ) )
{
HBufC* noteText = NULL;
noteText = StringLoader::LoadLC( R_IAUPDATE_INSUFFICIENT_MEMORY );
IAUpdateDialogUtil::ShowInformationQueryL( *noteText );
CleanupStack::PopAndDestroy( noteText );
}
else
{
if ( !IsStartedByLauncher() )
{
if ( !iStarter )
{
// Notice, that the ownership of the filter parameters will
// remain in the filter.
CIAUpdateParameters* params = iFilter->FilterParams();
iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(),
params->CommandLineArguments() );
}
}
// Inform the controller that we are now starting updates. This way the
// controller can handle situations as a whole and not as one item at the
// time.
iController->StartingUpdatesL();
iFileInUseError = EFalse;
// Set the node index to -1 because ContinueUpdateL increases it by one
// in the beginning of the function. So, we can use the ContinueUpdateL
// also in here.
iNodeIndex = -1;
ContinueUpdateL( EFalse );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartUpdateL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ContinueUpdateL
// Continues software updating from the next node
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ContinueUpdateL( TBool aSelfUpdateFinished )
{
IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::ContinueUpdateL() begin: %d",
aSelfUpdateFinished );
// Get the node index of the next node.
// The node that is indexed by iNodeIndex has already been handled in
// previous loop. So, increase the temp index by one here as it will be done
// in the while loop below for real index.
TInt tmpIndex( iNodeIndex + 1 );
if ( tmpIndex > 0
&& tmpIndex < iSelectedNodesArray.Count()
&& iSelectedNodesArray[ tmpIndex - 1 ]->IsSelfUpdate()
&& !iSelectedNodesArray[ tmpIndex ]->IsSelfUpdate()
&& !aSelfUpdateFinished
&& iController->SelfUpdateDataExists() )
{
IAUPDATE_TRACE_1("[IAUPDATE] Self updates have been handled now: %d",
iNodeIndex);
// Self update should be started now because
// current node is not anymore self update and previous nodes were.
// UpdateCompleteL will start the self updater and inform observers.
// If no self update data can be found, then there has been some error
// when self update data has been set. So, then there is no reason to start
// self updater here. In that case, continue normally in the while loop below if
// other items are waiting for update.
iNodeIndex++;
UpdateCompleteL( KErrNone );
// Do not continue after this.
return;
}
TBool nextUpdate( ETrue );
while ( nextUpdate )
{
IAUPDATE_TRACE_1("[IAUPDATE] Next update while loop: %d",
iNodeIndex);
iNodeIndex++;
if ( iNodeIndex < iSelectedNodesArray.Count() )
{
MIAUpdateNode* selectedNode = iSelectedNodesArray[ iNodeIndex ];
// Only update items that have not been installed yet.
if ( !selectedNode->IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] Item not installed yet");
if ( !selectedNode->IsDownloaded() )
{
// Because content has not been downloaded or installed yet,
// it needs to be downloaded before it can be installed.
IAUPDATE_TRACE("[IAUPDATE] Download");
selectedNode->DownloadL( *this );
iState = EDownloading;
iClosingAllowedByClient = ETrue;
ShowUpdatingDialogL( R_IAUPDATE_DOWNLOADING_NOTE,
selectedNode->Base().Name(),
iNodeIndex + 1,
iSelectedNodesArray.Count() );
nextUpdate = EFalse;
}
else
{
// Because content has been downloaded but not installed yet,
// it needs to be installed now.
IAUPDATE_TRACE("[IAUPDATE] Install");
selectedNode->InstallL( *this );
iState = EInstalling;
iClosingAllowedByClient = EFalse;
CIAUpdateAppUi* appUi =
static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
appUi->StartWGListChangeMonitoring();
ShowUpdatingDialogL( R_IAUPDATE_INSTALLING_NOTE,
selectedNode->Base().Name(),
iNodeIndex + 1,
iSelectedNodesArray.Count() );
nextUpdate = EFalse;
}
}
}
else
{
IAUPDATE_TRACE("[IAUPDATE] Update flow complete");
nextUpdate = EFalse;
UpdateCompleteL( KErrNone );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ContinueUpdateL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartInstallL
// Starts software installing
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::StartInstallL( MIAUpdateNode& aNode )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartInstallL() begin");
if ( aNode.Type() == MIAUpdateNode::EPackageTypeServicePack )
{
iServicePackNodes.Reset();
aNode.GetDependenciesL( iServicePackNodes, ETrue );
}
aNode.InstallL( *this );
iState = EInstalling;
CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
appUi->StartWGListChangeMonitoring();
iClosingAllowedByClient = EFalse;
ShowUpdatingDialogL( R_IAUPDATE_INSTALLING_NOTE,
aNode.Base().Name(),
iNodeIndex + 1,
iSelectedNodesArray.Count() );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartInstallL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartRefreshL()
// Starts meta data refresh
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::StartRefreshL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartRefreshL() begin");
iCountOfAvailableUpdates = 0;
iClosingAllowedByClient = ETrue;
if ( iOffConfigurated )
{
iObserver.RefreshCompleteL( ETrue, KErrNone );
}
else
{
iState = ERefreshing;
TBool allowNetworkRefresh = AllowNetworkRefreshL();
iSelectedNodesArray.Reset();
iController->StartRefreshL( allowNetworkRefresh );
if ( iRequestType == IAUpdateUiDefines::ECheckUpdates && iFilter->FilterParams() )
{
if ( iFilter->FilterParams()->ShowProgress() )
{
// to avoid flickering IAD is brought to foreground only when wait dialog is really shown
if ( allowNetworkRefresh )
{
iEikEnv->RootWin().SetOrdinalPosition( 0, ECoeWinPriorityNormal );
HBufC* noteText = StringLoader::LoadLC( R_IAUPDATE_REFRESHING_UPDATE_LIST );
ShowWaitDialogL( *noteText, ETrue );
CleanupStack::PopAndDestroy( noteText );
}
}
}
else
{
HBufC* noteText = StringLoader::LoadLC( R_IAUPDATE_REFRESHING_UPDATE_LIST );
ShowWaitDialogL( *noteText, EFalse );
CleanupStack::PopAndDestroy( noteText );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartRefreshL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::Nodes
//
// ---------------------------------------------------------------------------
//
const RPointerArray< MIAUpdateNode >& CIAUpdateUiController::Nodes() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Nodes()");
return iNodes;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::FwNodes
//
// ---------------------------------------------------------------------------
//
const RPointerArray<MIAUpdateFwNode>& CIAUpdateUiController::FwNodes() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::FwNodes()");
return iFwNodes;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::HistoryL
//
// ---------------------------------------------------------------------------
//
MIAUpdateHistory& CIAUpdateUiController::HistoryL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HistoryL()");
return iController->HistoryL();
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::SetRequestType
//
// ---------------------------------------------------------------------------
void CIAUpdateUiController::SetRequestType(
IAUpdateUiDefines::TIAUpdateUiRequestType aRequestType )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetRequestType() begin");
IAUPDATE_TRACE_1("[IAUPDATE] request type: %d", aRequestType );
iRequestType = aRequestType;
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SetRequestType() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::CancelOperation
//
// ---------------------------------------------------------------------------
void CIAUpdateUiController::CancelOperation()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CancelOperation() begin");
// Set the flag to inform possible callback functions
// that operation cancell is going on.
iCancelling = ETrue;
if ( iIdle )
{
iIdle->Cancel();
}
if ( iStarter )
{
iStarter->Cancel();
}
if ( iRoamingHandler )
{
iRoamingHandler->CancelPreparing();
}
if ( iState == EDownloading || iState == EInstalling )
{
// Current node.
MIAUpdateNode* node( iSelectedNodesArray[ iNodeIndex ] );
// Cancel the operation of that node.
node->CancelOperation();
// Also set the purchase history information to other nodes
// even if their operations were not started yet.
for ( TInt i = iNodeIndex + 1; i < iSelectedNodesArray.Count(); ++i )
{
node = iSelectedNodesArray[ i ];
if ( MIAUpdateNode::EPackageTypeServicePack == node->Type()
&& node->IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] Service pack was completed");
// Even if cancel occurred, some of the nodes inside the
// service pack were installed from some other dependency
// chain way. And, now there is nothing to be installed
// inside the service pack.
TRAP_IGNORE ( node->Base().
SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue ) );
}
else
{
IAUPDATE_TRACE("[IAUPDATE] Node cancelled");
// Notice, that this can also still be service pack node.
// Because we are handling nodes that are visible in UI,
// we can force the node as visible in history.
TRAP_IGNORE (
node->Base().SetIdleCancelToPurchaseHistoryL( ETrue ) );
}
}
}
else if ( iState == ERefreshing )
{
iController->CancelRefresh();
}
// Just to be sure that self update related information
// is always in resetted state when new update flows are
// started after operation cancel.
if ( iController )
{
iController->ResetSelfUpdate();
}
// After cancellation, the new state is idle.
iState = EIdle;
iClosingAllowedByClient = ETrue;
// Cancelling is over. So, set the flag accrodingly.
iCancelling = EFalse;
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CancelOperation() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ResultsInfo
//
// ---------------------------------------------------------------------------
TIAUpdateResultsInfo CIAUpdateUiController::ResultsInfo() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ResultsInfo() begin");
TIAUpdateResultsInfo resultsInfo( 0, 0, 0, iFileInUseError, EFalse );
for ( TInt i = 0; i < iSelectedNodesArray.Count(); ++i )
{
MIAUpdateNode* node( iSelectedNodesArray[ i ] );
TInt lastErrorCode( KErrNone );
TRAPD ( trapError,
lastErrorCode = node->Base().LastUpdateErrorCodeL() );
if ( node->IsInstalled() )
{
// Because node is installed, update must have been a success.
++resultsInfo.iCountSuccessfull;
if ( node->Base().RebootAfterInstall() )
{
resultsInfo.iRebootAfterInstall = ETrue;
}
}
else if ( trapError == KErrNone
&& lastErrorCode == KErrCancel )
{
++resultsInfo.iCountCancelled;
}
else
{
++resultsInfo.iCountFailed;
}
}
IAUPDATE_TRACE_1("[IAUPDATE] Successfull count: %d", resultsInfo.iCountSuccessfull );
IAUPDATE_TRACE_1("[IAUPDATE] Cancelled count: %d", resultsInfo.iCountCancelled );
IAUPDATE_TRACE_1("[IAUPDATE] Failed count: %d", resultsInfo.iCountFailed );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ResultsInfo() end");
return resultsInfo;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::CountOfAvailableUpdates
//
// ---------------------------------------------------------------------------
TInt CIAUpdateUiController::CountOfAvailableUpdates() const
{
IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::CountOfAvailableUpdates() count: %d",
iCountOfAvailableUpdates );
return iCountOfAvailableUpdates;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::Starter()
//
// ---------------------------------------------------------------------------
const CIAUpdateStarter* CIAUpdateUiController::Starter() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Starter()");
return iStarter;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::Filter()
//
// ---------------------------------------------------------------------------
const CIAUpdateNodeFilter* CIAUpdateUiController::Filter() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::Filter()");
return iFilter;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::DoCancelIfAllowed
//
// -----------------------------------------------------------------------------
//
TBool CIAUpdateUiController::DoCancelIfAllowed()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DoCancelIfAllowed() begin");
if ( iClosingAllowedByClient )
{
CancelOperation();
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DoCancelIfAllowed() end");
return iClosingAllowedByClient;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::ClosingAllowedByClient
//
// -----------------------------------------------------------------------------
//
TBool CIAUpdateUiController::ClosingAllowedByClient()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ClosingAllowedByClient()");
IAUPDATE_TRACE_1("[IAUPDATE] closing allowed: %d", iClosingAllowedByClient );
TBool closingAllowed = iClosingAllowedByClient;
if ( iRequestType != IAUpdateUiDefines::EShowUpdates )
{
// iaupdate can be orphaned from its client only when ShowUpdates() was called
closingAllowed = ETrue;
}
return closingAllowed;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::CheckUpdatesDeferredL
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::CheckUpdatesDeferredL( CIAUpdateParameters* aParams,
TBool aRefreshFromNetworkDenied )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredL() begin");
iClosingAllowedByClient = ETrue;
delete iParams;
iParams = aParams; //ownership of parameters is taken
iRefreshFromNetworkDenied = aRefreshFromNetworkDenied;
delete iIdle;
iIdle = NULL;
iIdle = CIdle::NewL( CActive::EPriorityIdle );
iIdle->Start( TCallBack( CheckUpdatesDeferredCallbackL, this ) );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredL() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::PrepareRoamingHandlerL
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::PrepareRoamingHandlerL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::PrepareRoamingHandlerL() begin");
if ( !iRoamingHandler )
{
iRoamingHandler = CIAUpdateRoamingHandler::NewL();
}
if ( !iRoamingHandler->Prepared() )
{
iRoamingHandler->CancelPreparing();
//async call that will return in RoamingHandlerPrepared()
iRoamingHandler->PrepareL( *this );
}
else
{
CheckUpdatesL();
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::PrepareRoamingHandlerL() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::HandlePossibleSelfUpdateRestartL
//
// -----------------------------------------------------------------------------
//
TBool CIAUpdateUiController::HandlePossibleSelfUpdateRestartL( TBool aShutdownRequest )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandlePossibleSelfUpdateRestartL() begin");
IAUPDATE_TRACE_1("[IAUPDATE] ShutdownRequest: %d", aShutdownRequest );
TBool restarted( EFalse );
CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() );
if ( info )
{
IAUPDATE_TRACE("[IAUPDATE] Self updater related info available.");
CleanupStack::PushL( info );
// Delete the unnecessary files because we will still have
// required objects available.
// Notice, that if for some reason a leave occurs after this and the
// application does not continue the update, then next time the application
// is started, update restart is not rehandled any more.
info->DeleteFiles();
// Get the data for the updater results.
CIAUpdaterResultsFile& results( info->ResultsFile() );
// This flag is set if self updater operation was cancelled.
TBool selfUpdateCancelled( EFalse );
// Because we have restarted the iaupdate after self updating,
// also start to gather possible new update flow reports into
// a report bundle. Inform the controller, so the controller
// can handle situations as a whole and not as one item at the
// time.
iController->StartingUpdatesL();
RPointerArray< CIAUpdaterResult >& resultArray( results.Results() );
// Because self updater will insert the possible hidden dependencies
// before the actual item, start from the beginning of the array to
// set the error codes. This way, the main item will be set last and
// it will get the latest time for the purchase history.
for ( TInt i = 0; i < resultArray.Count(); ++i )
{
CIAUpdaterResult* result( resultArray[ i ] );
if ( result->ErrorCode() == KErrCancel )
{
IAUPDATE_TRACE("[IAUPDATE] Self Updater cancelled");
selfUpdateCancelled = ETrue;
}
// Because, the self update installation was finished.
// Update the purchase history with the correct information.
// Notice, that we can just set the purchase history here for
// the self updater items. If some of the items were installed,
// before self updater items, then their information was already
// correctly into the history. Notice, that result nodes may be hidden
// nodes that were not initially visible in the UI. So, do not
// force the results visible in purchase history.
MIAUpdateNode& node( iController->NodeL( result->Identifier() ) );
node.Base().
SetInstallStatusToPurchaseHistoryL(
result->ErrorCode(), EFalse );
}
IAUPDATE_TRACE("[IAUPDATE] Self update info inserted to purchase history.");
// Get the data for the pending node info.
CIAUpdatePendingNodesFile& pendings(
info->PendingNodesFile() );
// Because ContinueUpdateL will use the counters and
// node index and iSelectedNodesArray, we set the correponding information
// here. Then, the update operation will continue correctly for the pending
// nodes.
// Set the node index to -1 because ContinueUpdateL increases it by one
// in the beginning of the function. So, we can use the ContinueUpdateL
// also in the end of this function to start the actual update process.
iNodeIndex = -1;
iSelectedNodesArray.Reset();
// Also, reset nodearray nodes as not selected because original parameter
// settings may have been overruled by the user before user started
// the self update from UI. Correct nodes will be chosen in the for-loops below.
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
MIAUpdateNode& node( *iNodes[ i ] );
node.Base().SetSelected( EFalse );
}
for ( TInt i = 0; i < iFwNodes.Count(); ++i )
{
MIAUpdateFwNode& fwNode( *iFwNodes[ i ] );
fwNode.Base().SetSelected( EFalse );
}
if ( !selfUpdateCancelled )
{
IAUPDATE_TRACE("[IAUPDATE] Self update not cancelled.");
// Notice, that the ownership of the filter parameters will
// remain in the filter.
CIAUpdateParameters* params( iFilter->FilterParams() );
if ( !IsStartedByLauncher() || params )
{
IAUPDATE_TRACE("[IAUPDATE] Self update handling will set parameters.");
// Check if IAD was started from the grid or through API.
// If IAD was started like from the grid but it still has parameters set,
// then act as it was started through API. Most likely, then the IAD was
// originally started through API but because of self update IAD was restarted
// and now it has original parameters set.
if ( !iStarter )
{
IAUPDATE_TRACE("[IAUPDATE] iStarter not set");
iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(),
params->CommandLineArguments() );
}
}
}
// Get list of nodes that were initially chosen for the flow.
RPointerArray< CIAUpdaterIdentifier >& pendingIdentifiers =
pendings.PendingNodes();
TInt pendingIdentifiersCount( pendingIdentifiers.Count() );
// Get the index to the node that has not yet been handled.
TInt pendingsIndex( pendings.Index() );
iSelectedNodesArray.ReserveL( pendingIdentifiersCount );
for ( TInt i = 0; i < pendingIdentifiersCount; ++i )
{
CIAUpdaterIdentifier* identifier( pendingIdentifiers[ i ] );
MIAUpdateNode& node(
iController->NodeL( *identifier ) );
iSelectedNodesArray.AppendL( &node );
// Also, set the node as selected because then UI can easily check
// which nodes should be marked when the UI is restarted after selfupdate.
node.Base().SetSelected( ETrue );
if ( i < pendingsIndex )
{
// We come here if index suggests that node has already been handled
// Increase the node index. So, it will already point
// to the correct place. Because, we want to omit these files
// when list is gone through.
++iNodeIndex;
if ( iStarter && node.IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] Self update handling will set parameters, node installed");
// Because application starting parameters may have been given through the
// API, we need to pass UID of installed package to starter if it exists.
// Then, the starter will start the given exe in the end of the install flow
// if at least one file was succesfully installed.
iStarter->CheckInstalledPackageL( node.Base().Uid() );
}
}
else if ( selfUpdateCancelled )
{
IAUPDATE_TRACE("[IAUPDATE] Set idle cancel info to purchase history");
// Check if self updater actions were cancelled.
// Set the purchase history information to nodes not handled yet.
// If visible service pack was changed to hidden during the operation
// then force the current history info visible. Then the history
// corresponds the situation that was when operation flow was started.
// This may occure if some of the items were installed after all.
// Notice, that here we can think that node was initially visible
// because all nodes in UI selection list are visible and possible
// hidden self update nodes have been handled already in the beginning
// of this for loop.
if ( MIAUpdateNode::EPackageTypeServicePack == node.Type()
&& node.IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] Service pack was completed");
// Even if cancel occurred, some of the nodes inside the
// service pack were installed. And, now there is nothing
// to be installed inside the service pack.
node.Base().
SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue );
}
else
{
IAUPDATE_TRACE("[IAUPDATE] Node cancelled");
// Notice, that this can also still be service pack node.
// Because we are handling nodes that are visible in UI,
// we can force the node as visible in history.
node.Base().SetIdleCancelToPurchaseHistoryL( ETrue );
}
}
else if ( MIAUpdateNode::EPackageTypeServicePack == node.Type()
&& node.IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] Service pack has become installed");
// Because service pack has become installed during self update
// it means that the service pack was originally missing only
// the selfupdate. Set, the service pack as installed also into
// purchase history because no other operation will be done to
// it after this. Notice, that because service pack was originally
// in the list, it has been visible for UI. So, make sure that it
// is also visible in history. IAD Engine will set service packs
// whose all content is installed as hidden. Therefore, force the
// visibility here.
// Notice, that here we can think that node was initially visible
// because all nodes in UI selection list are visible and possible
// hidden self update nodes have been handled already in the beginning
// of this for loop.
node.Base().
SetInstallStatusToPurchaseHistoryL( KErrNone, ETrue );
}
}
// Info is not needed any more.
// So, delete it before update flow will be continued below
// if necessary.
CleanupStack::PopAndDestroy( info );
// Check if self updater actions was closed by using red key.
// If so, then do not continue update flow here.
// Instead, this application should be closed.
if ( !aShutdownRequest )
{
IAUPDATE_TRACE("[IAUPDATE] Self update not closed with red key.");
if ( selfUpdateCancelled )
{
IAUPDATE_TRACE("[IAUPDATE] Self update cancelled.");
// Because self update is cancelled, do not continue here either.
// Instead end the update flow directly.
UpdateCompleteL( KErrCancel );
}
else
{
IAUPDATE_TRACE("[IAUPDATE] Self update finished, continue udpate.");
// Continue udpate normally.
ContinueUpdateL( ETrue );
}
}
else
{
IAUPDATE_TRACE("[IAUPDATE] Self update closed with red key. Handle dialogs.");
// Because shutdown was requested, we do not continue the update flow.
// A updating dialog may still show. So, release it here.
RemoveUpdatingDialogsL();
}
// Self updater provided some data that was handeld above.
restarted = ETrue;
}
IAUPDATE_TRACE_1("[IAUPDATE] restarted: %d", restarted );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandlePossibleSelfUpdateRestartL() end");
return restarted;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::TestRole
//
// -----------------------------------------------------------------------------
//
TBool CIAUpdateUiController::TestRole() const
{
return iTestRole;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::RefreshComplete
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::RefreshComplete(
const RPointerArray< MIAUpdateAnyNode >& aNodes,
TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshComplete() begin");
TInt completionError = KErrNone;
if ( iState == EUiRefreshing )
{
iState = EIdle;
TRAP( completionError, RefreshUiCompleteL( aNodes, aError ) );
}
else
{
iState = EIdle;
TRAP ( completionError, RemoveWaitDialogL() );
if ( completionError == KErrNone )
{
TRAP( completionError, RefreshCompleteL( aNodes, aError ) );
}
}
if ( completionError == KErrNone )
{
iRefreshed = ETrue;
}
else
{
iObserver.HandleLeaveErrorWithoutLeave( completionError );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshComplete() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::SelfUpdaterComplete
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::SelfUpdaterComplete( TInt aErrorCode )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SelfUpdaterComplete() begin");
IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aErrorCode );
// Self updater completed its job.
// Normally we should not come here because self update should shut down this
// application before installation. But, now because we came here, complete
// the update operation.
// Remove params file if it exists. This is a temporary file that would be
// otherwise read during next grid start if not removed here. There is no need
// to use that file now, because all the necessary parameters are already set
// because restart of IAD did not occur.
iState = EIdle;
TRAP_IGNORE ( ParamsRemoveFileL() );
TInt err( KErrNone );
TBool restartDataWasAvailable( EFalse );
TRAP ( err,
restartDataWasAvailable =
HandlePossibleSelfUpdateRestartL(
aErrorCode == IAUpdaterDefs::KIAUpdaterShutdownRequest ) );
if ( err != KErrNone )
{
iObserver.HandleLeaveErrorWithoutLeave( err );
}
else if ( !restartDataWasAvailable )
{
IAUPDATE_TRACE("[IAUPDATE] Restart data not available");
// For some reason the self updater was not able to give the restart data.
// So, try to continue the update in a normal way.
TRAP ( err, UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( aErrorCode ) );
if ( err == KErrNone )
{
IAUPDATE_TRACE("[IAUPDATE] Continue update flow");
TRAP ( err, ContinueUpdateL( EFalse ) );
}
if ( err != KErrNone )
{
IAUPDATE_TRACE_1("[IAUPDATE] Purchase history update error: %d", err);
iObserver.HandleLeaveErrorWithoutLeave( err );
}
}
if ( aErrorCode == IAUpdaterDefs::KIAUpdaterShutdownRequest )
{
CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
appUi->Exit();
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::SelfUpdaterComplete() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::ServerReportSent
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::ServerReportSent( TInt aError )
{
IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::ServerReportSent() begin: %d",
aError);
// This call back is called when MIAUpdateController::UpdateFinishedL
// function is called and that asynchronous operation completes.
// Report sending is done in the background.
if ( iState == ESendingReport )
{
IAUPDATE_TRACE("[IAUPDATE] End the update flow now that report has been sent");
// Reports are sent only when update flow has finished. Also, in normal
// flow, we wait that report sending finishes before continuing to the end.
TRAP_IGNORE( EndUpdateFlowL( aError ) );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ServerReportSent() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::ClientRole
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::ClientRole( const TDesC& aClientRole )
{
if ( aClientRole == IAUpdateUiDefines::KTestRole() )
{
iTestRole = ETrue;
}
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::DownloadProgress
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::DownloadProgress( MIAUpdateNode& /*aNode*/,
TUint aProgress,
TUint aMaxProgress )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadProgress() begin");
if ( iProgressDialog )
{
TRAP_IGNORE ( iProgressDialog->SetProgressDialogFinalValueL( aMaxProgress ) );
TRAP_IGNORE ( iProgressDialog->UpdateProgressDialogValueL( aProgress ) );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadProgress() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::DownloadComplete
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::DownloadComplete( MIAUpdateNode& aNode,
TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadComplete() begin");
iState = EIdle;
TRAPD ( completionError, DownloadCompleteL( aNode, aError ) );
if ( completionError != KErrNone )
{
// If we came here, DownloadCompleteL function may have left
// before dialog was removed. So, try one more time to remove it here
// before informing the observer.
TRAP_IGNORE( RemoveUpdatingDialogsL() );
iObserver.HandleLeaveErrorWithoutLeave( completionError );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadComplete() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::InstallProgress
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::InstallProgress( MIAUpdateNode& /*aNode*/,
TUint /*aProgress*/,
TUint /*aMaxProgress*/ )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallProgress()");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::InstallComplete
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::InstallComplete( MIAUpdateNode& aNode,
TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallComplete() begin");
iState = EIdle;
CIAUpdateAppUi* appUi = static_cast<CIAUpdateAppUi*>( iEikEnv->EikAppUi() );
appUi->StopWGListChangeMonitoring();
if ( aError == SwiUI::KSWInstErrFileInUse )
{
iFileInUseError = ETrue;
}
TRAPD ( completionError, InstallCompleteL( aNode, aError ) );
if ( completionError != KErrNone )
{
// If we came here, InstallCompleteL function may have left
// before dialog was removed. So, try one more time to remove it here
// before informing the observer.
TRAP_IGNORE( RemoveUpdatingDialogsL() );
iObserver.HandleLeaveErrorWithoutLeave( completionError );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallComplete() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartupComplete
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::StartupComplete( TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartupComplete() begin");
if ( aError == IAUpdateErrorCodes::KErrCacheCleared )
{
IAUPDATE_TRACE("[IAUPDATE] Cache cleared during startup.");
// Because cache was cleared, change the refresh information data
// so that the network refresh will be done during refresh operation.
// The values have been read from the file when the controller file
// object was created or the defaul values are used if the file did
// not exist. So, no need to re-read them here.
// Replace the time with zero. So, the zero time will
// suggest that network refresh is required later on.
iControllerFile->SetRefreshTime( 0 );
// Save data into the file.
// Change aError value to correct one.
// aError will be KErrNone if everything goes ok inside trap,
// or else it will contain the correct error code.
TRAP ( aError, iControllerFile->WriteControllerDataL(); );
CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() );
if ( info )
{
IAUPDATE_TRACE("[IAUPDATE] Delete restart info because of cache clean.");
// Restart info was available.
// Delete self upate files because otherwise a net connection
// may be prevented during refresh and the cleared cache can not
// be updated. If this is not done here, HandlePossibleSelfUpdateRestartL
// may leave because required nodes are not found. Notice, that also
// HandlePossibleSelfUpdateRestartL deletes these files but by handling
// this special case here, an application can continue without leave later.
info->DeleteFiles();
delete info;
info = NULL;
}
}
iObserver.StartupComplete( aError );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartupComplete() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartExecutableCompletedL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::StartExecutableCompletedL( TInt /*aError*/ )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartExecutableCompletedL() begin");
// Before informing the observer, close the possible existing dialog.
RemoveUpdatingDialogsL();
// Possible error is not passed to a client. Typically client is already closed.
// Even in the case when client's request is still ongoing, it's disinformation to return
// error from failed executable start.
TRAPD ( err, iObserver.UpdateCompleteL( KErrNone ) );
if ( err != KErrNone )
{
iObserver.HandleLeaveErrorL( err );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartExecutableCompletedL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RoamingHandlerPrepared
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RoamingHandlerPrepared()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RoamingHandlerPrepared() begin");
TRAPD ( err, CheckUpdatesL() );
if ( err != KErrNone )
{
iObserver.HandleLeaveErrorWithoutLeave( err );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RoamingHandlerPrepared() end");
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::HandleDialogExitL
// Called when wait/progress dialog is about to be cancelled.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TBool CIAUpdateUiController::HandleDialogExitL( TInt aButtonId )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleDialogExitL() begin");
IAUPDATE_TRACE_1("[IAUPDATE] button id: %d", aButtonId );
TInt ret( ETrue );
if ( aButtonId == EAknSoftkeyCancel )
{
TRAPD ( err, HandleUserCancelL() );
if ( err != KErrNone )
{
iObserver.HandleLeaveErrorL( err );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleDialogExitL() end");
return ret;
}
// -----------------------------------------------------------------------------
// CIAUpdateUiController::HandleUiRefreshL
//
// -----------------------------------------------------------------------------
//
void CIAUpdateUiController::HandleUiRefreshL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUiRefreshL() begin");
if ( iRequestType == IAUpdateUiDefines::ECheckUpdates )
{
iRefreshed = EFalse;
}
else if ( iState == EIdle )
{
CIAUpdateAppUi* appUi = static_cast< CIAUpdateAppUi* >( iEikEnv->EikAppUi() );
if ( appUi->UiRefreshAllowed() )
{
iState = EUiRefreshing;
// store node identification (package UID and version) of currently selected nodes
// to restore selections after refresh
delete iPreviousSelections;
iPreviousSelections = NULL;
iPreviousSelections = new( ELeave ) CArrayFixFlat<SIAUpdateNodeId>( iNodes.Count() + 1 );
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
MIAUpdateNode* node( iNodes[ i ] );
SIAUpdateNodeId nodeId;
nodeId.iNodeType = MIAUpdateAnyNode::ENodeTypeNormal;
nodeId.iPackageUid = node->Base().Uid();
nodeId.iVersion = node->Base().Version();
nodeId.iSelected = node->Base().IsSelected();
iPreviousSelections->AppendL( nodeId );
}
if ( iFwNodes.Count() > 0 )
{
MIAUpdateFwNode* fwNode( iFwNodes[ 0 ] );
SIAUpdateNodeId nodeId;
nodeId.iNodeType = MIAUpdateAnyNode::ENodeTypeFw;
nodeId.iSelected = fwNode->Base().IsSelected();
iPreviousSelections->AppendL( nodeId );
}
iController->StartRefreshL( EFalse );
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUiRefreshL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RefreshCompleteL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RefreshCompleteL(
const RPointerArray< MIAUpdateAnyNode >& aNodes,
TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshCompleteL() begin");
iState = EIdle;
if ( !iRefreshHandler && !iOffConfigurated )
{
iRefreshHandler = CIAUpdateRefreshHandler::NewL();
}
if ( aError == KErrNone )
{
// Inform refresh to other IAD instances
if ( !iOffConfigurated && AllowNetworkRefreshL() && iRefreshHandler )
{
iRefreshHandler->InformRefreshL();
}
// Because refresh was successfully completed,
// update the controller information to the controller file
UpdateControllerFileL();
}
// Even in a case when refresh failed, there may be old cache available.
// It's also possible that only firmware node or normal node refresh failed, so there is
// partial list available
// ==> all nodes returned by engine are shown in UI
iNodes.Reset();
iFwNodes.Reset();
iNodes.ReserveL( aNodes.Count() );
for ( TInt i = 0; i < aNodes.Count(); ++i )
{
MIAUpdateAnyNode* anyNode( aNodes[ i ] );
if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeNormal )
{
MIAUpdateNode* node(
static_cast< MIAUpdateNode* >( anyNode ) );
iNodes.AppendL( node );
}
else if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw )
{
MIAUpdateFwNode* fwNode(
static_cast< MIAUpdateFwNode* >( anyNode ) );
iFwNodes.AppendL( fwNode );
}
}
switch ( iRequestType )
{
case IAUpdateUiDefines::ECheckUpdates:
if ( iFilter->FilterParams() )
{
iFilter->CountOfAvailableUpdatesL(
iNodes,
iFwNodes,
iCountOfAvailableUpdates );
}
break;
default:
// Sort the nodes according to the filter values
// This function performs default marking also
iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
break;
}
if ( aError == KErrNone )
{
// Now, that refresh has been done,
// check if there is some self update related settings .
HandlePossibleSelfUpdateRestartL( EFalse );
}
if ( !iOffConfigurated && iRefreshHandler )
{
iRefreshHandler->StartListeningL( this );
}
iObserver.RefreshCompleteL( ETrue, aError );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshCompleteL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RefreshUiCompleteL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RefreshUiCompleteL(
const RPointerArray< MIAUpdateAnyNode >& aNodes,
TInt /*aError*/ )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshUiCompleteL() begin");
// : Is error handling needed?
iNodes.Reset();
iFwNodes.Reset();
iNodes.ReserveL( aNodes.Count() );
// Find out if there was umarked firmware update in old selections,
// that case needs special handling
TBool unmarkedFw = EFalse;
for ( TInt i = 0; i < iPreviousSelections->Count(); ++i )
{
SIAUpdateNodeId prevNodeId = iPreviousSelections->At( i );
if ( prevNodeId.iNodeType == MIAUpdateAnyNode::ENodeTypeFw && !prevNodeId.iSelected )
{
unmarkedFw = ETrue;
}
}
for ( TInt i = 0; i < aNodes.Count(); ++i )
{
MIAUpdateAnyNode* anyNode( aNodes[ i ] );
if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeNormal )
{
MIAUpdateNode* node( static_cast< MIAUpdateNode* >( anyNode ) );
iNodes.AppendL( node );
}
else if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw && !unmarkedFw )
{
// if umarked firmware update in old selections, firmawares are not appended
// before iFilter->FilterAndSortNodesL() is called
MIAUpdateFwNode* fwNode(
static_cast< MIAUpdateFwNode* >( anyNode ) );
iFwNodes.AppendL( fwNode );
}
}
iFilter->FilterAndSortNodesL( iNodes, iFwNodes );
if ( unmarkedFw )
{
for ( TInt i = 0; i < aNodes.Count(); ++i )
{
MIAUpdateAnyNode* anyNode( aNodes[ i ] );
if ( anyNode->NodeType() == MIAUpdateAnyNode::ENodeTypeFw )
{
MIAUpdateFwNode* fwNode(
static_cast< MIAUpdateFwNode* >( anyNode ) );
iFwNodes.AppendL( fwNode );
}
}
}
//restore previous selections/deselections
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
MIAUpdateNode* node( iNodes[ i ] );
for ( TInt j = 0; j < iPreviousSelections->Count(); ++j )
{
SIAUpdateNodeId prevNodeId = iPreviousSelections->At(j);
if ( node->Base().Uid() == prevNodeId.iPackageUid &&
node->Base().Version() == prevNodeId.iVersion )
{
node->Base().SetSelected( prevNodeId.iSelected );
}
}
}
// When dependant is marked, all dependencies to be marked also
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
MIAUpdateNode* node( iNodes[ i ] );
if ( node->Base().IsSelected() )
{
iFilter->SetDependenciesSelectedL( *node, iNodes );
}
}
TBool firmwareSelected = EFalse;
for ( TInt i = 0; i < iFwNodes.Count(); ++i )
{
MIAUpdateFwNode* fwNode( iFwNodes[ i ] );
for ( TInt j = 0; j < iPreviousSelections->Count(); ++j )
{
SIAUpdateNodeId prevNodeId = iPreviousSelections->At(j);
if ( prevNodeId.iNodeType == MIAUpdateAnyNode::ENodeTypeFw )
{
fwNode->Base().SetSelected( prevNodeId.iSelected );
}
}
if ( fwNode->Base().IsSelected() )
{
firmwareSelected = ETrue;
}
}
// if firmware is marked, normal nodes to be unmarked
if ( firmwareSelected )
{
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
MIAUpdateNode* node( iNodes[ i ] );
node->Base().SetSelected( EFalse );
}
}
CreateSelectedNodesArrayL();
iObserver.RefreshCompleteL( EFalse, KErrNone );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RefreshUiCompleteL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::DownloadCompleteL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::DownloadCompleteL( MIAUpdateNode& aNode, TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadCompleteL() begin");
IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aError );
if ( aError == KErrAbort )
{
// Abort is interpreted so that a connection was not allowed by the user.
// So, do not continue to a new operation.
// Instead, complete the update flow now.
// Set the purchase history information to nodes.
// Because the current node has KErrAbort as the last operation error code,
// change it to KErrCancel because we want to think it as cancellation instead
// of as abort error. This way, error counters and history info will show cancel
// instead of failed. Also, update cancel info to other pending nodes.
for ( TInt i = iNodeIndex; i < iSelectedNodesArray.Count(); ++i )
{
MIAUpdateNode* node( iSelectedNodesArray[ i ] );
// Because we are handling nodes that are visible in UI,
// we can force the node as visible in history.
TRAP_IGNORE (
node->Base().SetIdleCancelToPurchaseHistoryL( ETrue ) );
}
UpdateCompleteL( KErrNone );
}
else if ( aError != KErrNone )
{
InstallCompleteL( aNode, aError );
}
else
{
StartInstallL( aNode );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::DownloadCompleteL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::InstallCompleteL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::InstallCompleteL( MIAUpdateNode& aNode,
TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() begin");
IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aError );
// In release mode, we do not need the aError info, because
// success counters are counted by using the last operation error info
// when counter info is asked. In debug mode the error code is logged above.
(void)aError;
// pass UID of installed package to starter
if ( iStarter )
{
if ( aNode.Type() == MIAUpdateNode::EPackageTypeServicePack )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node type is service pack");
for ( TInt i = 0; i < iServicePackNodes.Count(); ++i )
{
if ( iServicePackNodes[i]->IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node is installed");
iStarter->CheckInstalledPackageL( iServicePackNodes[i]->Base().Uid() );
}
}
iServicePackNodes.Reset();
}
else if ( aNode.IsInstalled() )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() node is installed");
iStarter->CheckInstalledPackageL( aNode.Base().Uid() );
}
}
// If installation was marked as KErrCancel here,
// we think that it was just the disclaimer and
// let this continue.
ContinueUpdateL( EFalse );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::InstallCompleteL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::UpdateCompleteL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::UpdateCompleteL( TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateCompleteL() begin");
iState = EIdle;
iClosingAllowedByClient = EFalse;
// Remove installed nodes from the node array.
for ( TInt i = iNodes.Count() - 1; i >= 0; --i )
{
MIAUpdateNode* node = iNodes[ i ];
if ( node->IsInstalled() )
{
iNodes.Remove( i );
}
}
TInt error( aError );
TBool selfUpdaterStarted( EFalse );
if ( error == KErrNone )
{
IAUPDATE_TRACE("[IAUPDATE] Check self update start");
// Set the error to correspond to the trap error. So,
// the observer will get correct information about the end result
// of the update.
TRAP ( error,
selfUpdaterStarted = StartPossibleSelfUpdateL() );
if ( error != KErrNone )
{
IAUPDATE_TRACE_1("[IAUPDATE] trap error: %d", error);
// Because self update could not be started the counters may not be
// correct. Also, update purchase history with the error value
// because install operation failed here.
UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( error );
}
}
// Check if self updater was started.
// If it was not, then there most likely was not any self updates set,
// or something went wrong when self updater was tried to be started.
if ( selfUpdaterStarted )
{
iState = ESelfUpdating;
}
else
{
IAUPDATE_TRACE("[IAUPDATE] SelfUpdater was not started");
// Notice, that if the self updater was started, then
// do not inform the UI here that the operation was completed.
// Also, do not start possible executable yet.
// Instead, let the self updater do its thing in the background.
// Most likely, the updater will close this application during installation.
// But, if it does not, it will result to the SelfUpdaterComplete function
// call, and we can continue the installation from there.
// Inform the controller that we finished the updates. This way the
// controller can handle situations as a whole and not as one item at the
// time. Notice, that this will start the asynchronous operation that sends
// possible reports to the server. Callback is called when operation is finished.
// Also notice, that this reporting operation is not part of the normal update
// flow but a separate action meant after update flow finishes.
// The destructor of the engine controller can handle the cancellation of
// the reporting operation. Also, no callbacks are called back to UI when
// cancellation occurs. Notice, that if close request for application is issued
// before reports are sent, then objects are delete immediately and we will not
// wait report sending to finish but reports are sent next time the application
// is started.
// Maximum wait time for server reports is given in micro seconds.
// Notice, that in case of cancellations there would not be any need
// for timer. But just use it as in normal cases. Then, server report
// completion or timer will call the callback later. But, that callback
// will be ignored in CIAUpdateUiController::ServerReportSent because
// iState is already then changed from ESendingReport to something else.
const TInt KServerReportMaxWaitTime( 10000000 );
iController->FinishedUpdatesL( ETrue, KServerReportMaxWaitTime );
iState = ESendingReport;
}
// When reports are sent, EndUpdateFlowL is called via the callback functions
// and the update flow will be finished there. But, if we come here when cancel
// is pressed, then call EndUpdateFlowL directly because then we do not wait
// report sending to finish. This will also set the state to EIdle to inform
// that when cancelling, we do not wait for the report sending to complete.
if ( aError == KErrCancel )
{
IAUPDATE_TRACE("[IAUPDATE] Cancelling. Call EndUpdateFlowL directly");
EndUpdateFlowL( error );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateCompleteL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::EndUpdateFlowL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::EndUpdateFlowL( TInt aError )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::EndUpdateFlowL() begin");
// Because we are ending the flow, set the state to idle.
iState = EIdle;
// Notice, that the ownership of the filter parameters will
// remain in the filter.
CIAUpdateParameters* params( iFilter->FilterParams() );
if ( !IsStartedByLauncher()
|| params )
{
IAUPDATE_TRACE_1("[IAUPDATE] Request type check matched: %d", iRequestType);
// Check if IAD was started from the grid or through API.
// If IAD was started like from the grid but it still has parameters set,
// then act as it was started through API. Most likely, then the IAD was
// originally started through API but because of self update IAD was restarted
// and now it has original parameters set.
if ( !iStarter )
{
IAUPDATE_TRACE("[IAUPDATE] iStarter not set");
iStarter = CIAUpdateStarter::NewL( params->CommandLineExecutable(),
params->CommandLineArguments() );
}
// Notice, that when starter calls StartExecutableCompletedL callback function,
// the observer is informed from there about the completion of the update flow.
// So, do not inform observer here.
iStarter->StartExecutableL( *this );
}
else
{
// Do not try to start any application.
// But, use the start application callback function
// to end the update flow correctly (same way as after
// application start with other options).
IAUPDATE_TRACE_1("[IAUPDATE] Update complete error: %d", aError );
StartExecutableCompletedL( aError );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::EndUpdateFlowL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::CheckUpdatesDeferredCallbackL
// CheckUpdates as deferred to get empty main view visible before CheckUpdates
//
// ---------------------------------------------------------------------------
//
TInt CIAUpdateUiController::CheckUpdatesDeferredCallbackL( TAny* aPtr )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredCallbackL() begin");
CIAUpdateUiController* uiCtrl = static_cast<CIAUpdateUiController*>( aPtr );
TRAPD ( err, uiCtrl->PrepareRoamingHandlerL() );
if ( err != KErrNone )
{
uiCtrl->iObserver.HandleLeaveErrorL( err );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CheckUpdatesDeferredCallbackL() end");
return KErrNone;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ShowUpdatingDialogL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ShowUpdatingDialogL( TInt aTextResourceId,
const TDesC& aName,
TInt aNumber,
TInt aTotalCount )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowUpdatingDialogL() begin");
// Before trying ot create a new dialog,
// remove possible existing dialog.
RemoveUpdatingDialogsL();
CDesCArray* stringArray = new( ELeave ) CDesCArrayFlat( 1 );
CleanupStack::PushL( stringArray );
stringArray->AppendL( aName );
CArrayFix<TInt>* numberArray = new( ELeave ) CArrayFixFlat<TInt>( 2 );
CleanupStack::PushL( numberArray );
numberArray->AppendL( aNumber );
numberArray->AppendL( aTotalCount );
HBufC* noteText = NULL;
noteText = StringLoader::LoadLC( aTextResourceId,
*stringArray,
*numberArray );
TPtr ptr = noteText->Des();
AknTextUtils::DisplayTextLanguageSpecificNumberConversion( ptr );
if ( iState == EDownloading )
{
ShowProgressDialogL( *noteText, ETrue );
}
else
{
ShowWaitDialogL( *noteText, ETrue );
}
CleanupStack::PopAndDestroy( noteText );
CleanupStack::PopAndDestroy( numberArray );
CleanupStack::PopAndDestroy( stringArray );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowUpdatingDialogL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ShowWaitDialogL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ShowWaitDialogL( const TDesC& aDisplayString,
TBool aVisibilityDelayOff )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowWaitDialogL() begin");
if ( iWaitDialog )
{
IAUPDATE_TRACE("[IAUPDATE] Wait dialog already existed. Remove it first");
// in some rare cases previous dialog still exists
// it's now just deleted (not recommended way) to avoid forwarding problem(s).
delete iWaitDialog;
iWaitDialog = NULL;
}
iWaitDialog =
new( ELeave ) CIAUpdateWaitDialog(
reinterpret_cast< CEikDialog** >( &iWaitDialog ),
aVisibilityDelayOff );
iWaitDialog->SetTextL( aDisplayString );
iWaitDialog->SetCallback( this );
iWaitDialog->ExecuteLD( R_IAUPDATE_WAIT_DIALOG );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowWaitDialogL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ShowProgressDialogL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ShowProgressDialogL( const TDesC& aDisplayString,
TBool aVisibilityDelayOff )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowProgressDialogL() begin");
if ( iProgressDialog )
{
IAUPDATE_TRACE("[IAUPDATE] Progress dialog already existed. Remove it first");
// in some rare cases previous dialog still exists
// it's now just deleted (not recommended way) to avoid forwarding problem(s).
delete iProgressDialog;
iProgressDialog = NULL;
}
iProgressDialog =
new( ELeave ) CIAUpdateProgressDialog(
reinterpret_cast< CEikDialog** >( &iProgressDialog ),
aVisibilityDelayOff );
iProgressDialog->SetTextL( aDisplayString );
iProgressDialog->SetCallback( this );
iProgressDialog->ExecuteLD( R_IAUPDATE_PROGRESS_DIALOG );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ShowProgressDialogL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RemoveUpdatingDialogsL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RemoveUpdatingDialogsL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveUpdatingDialogsL() begin");
RemoveWaitDialogL();
RemoveProgressDialogL();
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveUpdatingDialogsL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RemoveWaitDialogL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RemoveWaitDialogL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveWaitDialogL() begin");
if ( !iCancelling ) //that's needed because AVKON in 3.2.3 wk12, returning
//EFalse in TryToExitL() causes a crash
{
if ( iWaitDialog )
{
iWaitDialog->ProcessFinishedL();
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveWaitDialogL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RemoveProgressDialogL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::RemoveProgressDialogL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveProgressDialogL() begin");
if ( !iCancelling ) //that's needed because AVKON in 3.2.3 wk12, returning
//EFalse in TryToExitL() causes a crash
{
if ( iProgressDialog )
{
iProgressDialog->ProcessFinishedL();
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RemoveProgressDialogL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::AllowNetworkRefreshL
//
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::AllowNetworkRefreshL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::AllowNetworkRefreshL() begin");
TBool allowRefresh( EFalse );
if ( IsStartedByLauncher() )
{
if ( !iRefreshFromNetworkDenied &&
!iUserRoamingRejection &&
!RestartedFromSelfUpdate() )
{
if ( LocalNodesExpiredL() )
{
allowRefresh = ETrue;
}
}
}
else
{
// started by an application
if ( iFilter )
{
CIAUpdateParameters* params( iFilter->FilterParams() );
if ( params )
{
if ( params->Refresh() )
{
// Check from the central repocitory what are the automatic checking and
// roaming settings.
TInt autoUpdateCheckValue( 0 );
CRepository* cenrep(
CRepository::NewLC( KCRUidIAUpdateSettings ) );
// Notice, that KIAUpdateSettingAutoUpdateCheck can give following values
// 0 = No automatic update check
// 1 = Automatic update check enabled when not roaming
// 2 = Automatic update enabled
User::LeaveIfError( cenrep->Get( KIAUpdateAutoUpdateCheck,
autoUpdateCheckValue ) );
CleanupStack::PopAndDestroy( cenrep );
if ( ( autoUpdateCheckValue == EIAUpdateSettingValueEnable ) ||
( autoUpdateCheckValue == EIAUpdateSettingValueDisableWhenRoaming &&
!iRoamingHandler->IsRoaming() ) )
{
allowRefresh = ETrue;
}
}
}
}
}
IAUPDATE_TRACE_1("[IAUPDATE] allowRefresh: %d", allowRefresh );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::AllowNetworkRefreshL() end");
return allowRefresh;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::LocalNodesExpiredL
//
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::LocalNodesExpiredL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() begin");
// Notice, that the values for the iControllerFile, that are used here for
// expiration checkings, are set after successfull completion of refresh
// operation. See, UpdateControllerFileL that is called when operation
// finishes successfully.
const TTimeIntervalHours KExpirationDeltaInHours(
ConfigData().GridRefreshDeltaHours() );
// Make sure that the most current data is gotten from the file.
iControllerFile->ReadControllerDataL();
TLanguage currentLanguage = User::Language();
TLanguage lastTimeLanguage = iControllerFile->Language();
if ( lastTimeLanguage != currentLanguage )
{
// Think nodes as expired because the language
// has been changed in the phone. By updating the nodes,
// the items in UI will show correct language.
// No need to set the language to the controller file here.
// The value is set when the operation is successfully completed.
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() ETrue end");
return ETrue;
}
// Because the language check has passed,
// check also the time expirations.
// Get the last recorded refresh time from the controller file
TTime lastRefreshTime( iControllerFile->RefreshTime() );
// Initialize expireTime with the last refresh time. Notice,
// that this expire time will be increased below with the correct
// value
TTime expireTime( lastRefreshTime );
expireTime += KExpirationDeltaInHours;
// Get the current time.
TTime universalTime;
universalTime.UniversalTime();
if ( expireTime < universalTime
|| lastRefreshTime > universalTime )
{
// Database is expired because current time has passed the
// expiration time. Also, sanity check is made. If
// last refresh time is larger than current time, then the
// last refresh value has been set wrong, and the database can
// be thought as expired. This might be the case if the user has
// changed the time in the phone.
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() ETrue end");
return ETrue;
}
else
{
// Database is not expired yet.
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::LocalNodesExpiredL() EFalse end");
return EFalse;
}
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::UpdateControllerFileL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::UpdateControllerFileL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateControllerFileL() begin");
// This function is called after the refresh operation has
// completed.
// Check if local nodes were updated from the server.
// Notice, that last refresh time and language are both checked
// here when LocalNodesExpiredL() is called from AllowNetworkRefreshL.
// AllowNetworkRefreshL is called here because autoupdate and roaming checks
// should also be done when deciding if the nodes were updated.
if ( AllowNetworkRefreshL() )
{
// Update controller file with current information
// because old values were expired.
iControllerFile->SetCurrentData();
// Because data is not up to date,
// save new data into the file.
iControllerFile->WriteControllerDataL();
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateControllerFileL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::IsStartedByLauncher
//
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::IsStartedByLauncher()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IsStartedByLauncher()");
if ( iRequestType == IAUpdateUiDefines::ENoRequest )
{
IAUPDATE_TRACE("[IAUPDATE] Started by launcher");
// This operation was started from the application that was
// started by launcher
// Currently it means that launching is originated
// from application grid or background checker. There is only
// one iaupdate instance started by launcher
return ETrue;
}
else
{
IAUPDATE_TRACE("[IAUPDATE] NOT started by launcher");
// According to the request type,
// API was used to start the operation.
return EFalse;
}
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::StartPossibleSelfUpdateL
//
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::StartPossibleSelfUpdateL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartPossibleSelfUpdateL() begin");
// If there exist some self updater files that need to be installed
// separately, start self updating process.
TBool started(
iController->
StartPossibleSelfUpdateL( iNodeIndex,
iSelectedNodesArray.Count(),
iSelectedNodesArray,
EFalse ) );
// Because self updater has gotten all the information it needs now,
// we can reset the data that is meant for the updater.
iController->ResetSelfUpdate();
IAUPDATE_TRACE_1("[IAUPDATE] started: %d", started );
if ( started )
{
// Because self update was started, save possible parameters data
// for the possible restart of IAD. The, IAD can continue correctly.
ParamsWriteFileL();
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::StartPossibleSelfUpdateL() end");
return started;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL( TInt aErrorCode )
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL() begin");
IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", aErrorCode );
// Check all the items that have been updated so far.
// And, set the error info to purchase history accordingly.
for ( TInt i = 0;
i < iSelectedNodesArray.Count()
&& i < iNodeIndex + 1;
++i )
{
MIAUpdateNode* node( iSelectedNodesArray[ i ] );
if ( node->IsSelfUpdate() )
{
TBool installSuccess( node->IsInstalled() );
if ( !installSuccess )
{
// Notice, that we can just set the purchase history here for
// the self updater items. If some of the items were installed,
// before self updater items, then their information was already
// correctly into the history.
TInt error( aErrorCode );
if ( aErrorCode == KErrNone )
{
error = KErrUnknown;
}
// Because we are handling nodes that are visible in UI,
// we can force the node as visible in history.
node->Base().SetInstallStatusToPurchaseHistoryL( error, ETrue );
}
}
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::UpdateFailedSelfUpdaterInfoToPurchaseHistoryL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::HandleUserCancelL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::HandleUserCancelL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUserCancelL() begin");
// Get the current state.
// CancelOperation will set a new value for the state and we do not
// want to use that.
TState state( iState );
CancelOperation();
// Set the flag on.
// So, dialogs are handled correctly.
iCancelling = ETrue;
if ( state == EDownloading || state == EInstalling )
{
IAUPDATE_TRACE("[IAUPDATE] Cancel pressed while updating");
// Update flow is completed here.
// Notice, that this will also start the report sending,
// but we do not wait the sending to be complete before continuing.
UpdateCompleteL( KErrCancel );
}
else if ( state == ESendingReport )
{
IAUPDATE_TRACE("[IAUPDATE] Dialog cancel called while sending reports");
// Reports are sent only when update flow has finished.
// So, UpdateCompleteL has already been called and an update flow
// dialog is still being shown. Because cancel is called, complete
// flow without waiting for the report sending to finish.
EndUpdateFlowL( KErrCancel );
}
// Set the flag off because cancellation is over.
iCancelling = EFalse;
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::HandleUserCancelL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::RestartedFromSelfUpdate
//
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::RestartedFromSelfUpdate()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::RestartedFromSelfUpdate() begin");
TBool restarted( EFalse );
CIAUpdateRestartInfo* info( iController->SelfUpdateRestartInfo() );
if ( info )
{
// Restart info was available.
delete info;
info = NULL;
restarted = ETrue;
}
IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::RestartedFromSelfUpdate() end: %d",
restarted);
return restarted;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ParamsReadAndRemoveFileL
//
// ---------------------------------------------------------------------------
//
CIAUpdateParameters* CIAUpdateUiController::ParamsReadAndRemoveFileL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsReadAndRemoveFileL() begin");
CIAUpdateParameters* params( NULL );
CIAUpdateParametersFileManager* mgr( CIAUpdateParametersFileManager::NewLC() );
params = mgr->ReadL();
mgr->RemoveFile();
CleanupStack::PopAndDestroy( mgr );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsReadAndRemoveFileL() end");
return params;
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ParamsWriteFileL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ParamsWriteFileL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsWriteFileL() begin");
// Ownership is not transferred here.
CIAUpdateParameters* params( iFilter->FilterParams() );
if ( params )
{
CIAUpdateParametersFileManager* mgr(
CIAUpdateParametersFileManager::NewLC() );
mgr->WriteL( *params );
CleanupStack::PopAndDestroy( mgr );
}
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsWriteFileL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::ParamsRemoveFileL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::ParamsRemoveFileL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsRemoveFileL() begin");
CIAUpdateParametersFileManager* mgr(
CIAUpdateParametersFileManager::NewL() );
mgr->RemoveFile();
delete mgr;
mgr = NULL;
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::ParamsRemoveFileL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::CreateSelectedNodesArrayL
//
// ---------------------------------------------------------------------------
//
void CIAUpdateUiController::CreateSelectedNodesArrayL()
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CreateSelectedNodesArrayL() begin");
iSelectedNodesArray.Reset();
for ( TInt i = 0; i < iNodes.Count(); ++i )
{
if ( iNodes[ i ]->Base().IsSelected() )
{
iSelectedNodesArray.AppendL( iNodes[ i ] );
}
}
// Dependency nodes to be updated before their dependants.
// Also, self update nodes should be handled correctly.
iSelectedNodesArray.Sort(
TLinearOrder< MIAUpdateNode >( &SortSelectedNodes ) );
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::CreateSelectedNodesArrayL() end");
}
// ---------------------------------------------------------------------------
// CIAUpdateUiController::IAUpdateEnabledL()
// ---------------------------------------------------------------------------
//
TBool CIAUpdateUiController::IAUpdateEnabledL() const
{
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() begin");
TBool enabled = EFalse;
RFeatureControl featureControl;
TInt error( KErrNone );
error = featureControl.Connect();
IAUPDATE_TRACE_1("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() Connection to the Feature Manager Server: %d", error);
User::LeaveIfError( error );
TUid iaupdatefeature;
iaupdatefeature.iUid = KFeatureIdIAUpdate;
TInt ret = featureControl.FeatureSupported( iaupdatefeature );
if ( ret == KFeatureSupported )
{
enabled = ETrue;
}
featureControl.Close();
IAUPDATE_TRACE("[IAUPDATE] CIAUpdateUiController::IAUpdateEnabledL() end");
return enabled;
}
// End of File