diff -r 7333d7932ef7 -r 8b7f4e561641 iaupdate/IAD/api/client/src/iaupdatemanager.cpp --- a/iaupdate/IAD/api/client/src/iaupdatemanager.cpp Tue Aug 31 15:21:33 2010 +0300 +++ b/iaupdate/IAD/api/client/src/iaupdatemanager.cpp Wed Sep 01 12:22:02 2010 +0100 @@ -20,13 +20,15 @@ // INCLUDES #include +#include +#include +#include #include "iaupdatemanager.h" #include "iaupdateclient.h" #include "iaupdatedebug.h" - // ----------------------------------------------------------------------------- // CIAUpdateManager::NewL // @@ -49,9 +51,9 @@ CIAUpdateManager* CIAUpdateManager::NewLC( MIAUpdateObserver& aObserver ) { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::NewLC() begin"); - CIAUpdateManager* self = new( ELeave ) CIAUpdateManager(); + CIAUpdateManager* self = new( ELeave ) CIAUpdateManager( aObserver ); CleanupStack::PushL( self ); - self->ConstructL( aObserver ); + self->ConstructL(); IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::NewLC() end"); return self; } @@ -61,7 +63,10 @@ // // ----------------------------------------------------------------------------- // -CIAUpdateManager::CIAUpdateManager() +CIAUpdateManager::CIAUpdateManager( MIAUpdateObserver& aObserver ) +: CActive( CActive::EPriorityStandard ), + iObserver( aObserver ), + iUpdateType( EIAUpdateIdle ) { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CIAUpdateManager()"); iEikEnv = CEikonEnv::Static(); @@ -72,14 +77,10 @@ // // ----------------------------------------------------------------------------- // -void CIAUpdateManager::ConstructL( MIAUpdateObserver& aObserver ) +void CIAUpdateManager::ConstructL() { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::ConstructL() begin"); - iUpdateClient = new IAUpdateClient( aObserver ); - if ( !iUpdateClient ) - { - User::Leave(KErrNoMemory); - } + CActiveScheduler::Add( this ); if ( iEikEnv ) { iEikEnv->AddForegroundObserverL(*this); @@ -95,7 +96,12 @@ CIAUpdateManager::~CIAUpdateManager() { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::~CIAUpdateManager() begin"); - delete iUpdateClient; + delete iUpdateParameters; + iUpdateParameters = NULL; + // If an operation is still active, + // then DoCancel will cancel ongoing request + Cancel(); + UpdateClient().Close(); if ( iEikEnv ) { iEikEnv->RemoveForegroundObserver(*this); @@ -111,9 +117,60 @@ void CIAUpdateManager::CheckUpdates( const CIAUpdateParameters& aUpdateParameters ) { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CheckUpdates() begin"); - - iUpdateClient->checkUpdates( aUpdateParameters ); + if ( BusyCheck() ) + { + // An operation is already going on. + // Do not continue with this new operation. + // Only, inform the observer with the error code. + // Notice that the callback is called synchronously here + // because there is no better way to do it. Asynchronous way + // would be really cumbersome because this object is already active. + // This error is users fault. Therefore we, could also panic here. + Observer().CheckUpdatesComplete( KErrServerBusy, 0 ); + return; + } + + // Reset result values because we are starting a new operation. + ResetResults(); + // + delete iUpdateParameters; + iUpdateParameters = NULL; + TInt error = KErrNone; + TRAP(error,CopyUpdateParamsL( aUpdateParameters ) ); + if ( error == KErrNone ) + { + // Set the update type. + // So, we know later in RunL what operation was requested. + SetUpdateType( EIAUpdateStartServer ); + error = UpdateClient().OpenToBackroundAsync( iStatus); + } + + if ( error == KErrNone ) + { + // Set this object active. + // Because everything went ok, + // the operation will be handled asynchronously + // and the service provider will inform us when the operation + // is finished. + SetActive(); + } + else + { + // Because we are going to activate this active object, + // set the status pending. + iStatus = KRequestPending; + + // An error occurred above. + // Therefore, the operation did not proceed any further. + // Set this object active for asynchronous error handling. + SetActive(); + + // Now, that everything is ready, just inform the active scheduler + // that operation is finished. Pass the error code for the observer. + TRequestStatus* status( &iStatus ); + User::RequestComplete( status, error ); + } IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CheckUpdates() end"); } @@ -125,8 +182,62 @@ void CIAUpdateManager::ShowUpdates( const CIAUpdateParameters& aUpdateParameters ) { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::ShowUpdates() begin"); - iUpdateClient->showUpdates( aUpdateParameters ); + if ( BusyCheck() ) + { + // An update operation is already going on. + // Do not continue with this new operation. + // Only, inform the observer with the error code. + // Notice that the callback is called synchronously here + // because there is no better way to do it. Asynchronous way + // would be really cumbersome because this object is already active. + // This error is users fault. Therefore we, could also panic here. + Observer().UpdateComplete( KErrServerBusy, NULL ); + return; + } + + // Reset result values because we are starting a new operation. + ResetResults(); + // Set the update type. + // So, we know later in RunL what operation was requested. + SetUpdateType( EIAUpdateUpdate ); + + TInt error( UpdateClient().Open() ); + if ( error == KErrNone ) + { + error = + UpdateClient().ShowUpdates( aUpdateParameters, + iSuccessCount, + iFailCount, + iCancelCount, + iStatus ); + } + + if ( error == KErrNone ) + { + // Set this object active. + // Because everything went ok, + // the operation will be handled asynchronously + // and the service provider will inform us when the operation + // is finished. + SetActive(); + } + else + { + // Because we are going to activate this active object, + // set the status pending. + iStatus = KRequestPending; + + // An error occurred above. + // Therefore, the operation did not proceed any further. + // Set this object active for asynchronous error handling. + SetActive(); + + // Now, that everything is ready, just inform the active scheduler + // that operation is finished. Pass the error code for the observer. + TRequestStatus* status( &iStatus ); + User::RequestComplete( status, error ); + } IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::ShowUpdates() end"); } @@ -138,9 +249,9 @@ void CIAUpdateManager::Update( const CIAUpdateParameters& /*aUpdateParameters*/ ) { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::Update() begin"); - - iUpdateClient->update(); - + Observer().UpdateComplete( KErrNotSupported, NULL ); + + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::Update() begin"); } @@ -152,13 +263,259 @@ void CIAUpdateManager::UpdateQuery() { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::UpdateQuery() begin"); + if ( BusyCheck() ) + { + // An update operation is already going on. + // Do not continue with this new operation. + // Only, inform the observer with the error code. + // Notice that the callback is called synchronously here + // because there is no better way to do it. Asynchronous way + // would be really cumbersome because this object is already active. + // This error is users fault. Therefore we, could also panic here. + Observer().UpdateQueryComplete( KErrServerBusy, EFalse ); + return; + } + + // Reset result values because we are starting a new operation. + ResetResults(); + + // Set the update type. + // So, we know later in RunL what operation was requested. + SetUpdateType( EIAUpdateQuery ); + + TInt error( UpdateClient().Open() ); + if ( error == KErrNone ) + { + error = + UpdateClient().UpdateQuery( iUpdateNow, iStatus ); + } + + if ( error == KErrNone ) + { + // Set this object active. + // Because everything went ok, + // the operation will be handled asynchronously + // and the service provider will inform us when the operation + // is finished. + SetActive(); + } + else + { + // Because we are going to activate this active object, + // set the status pending. + iStatus = KRequestPending; - iUpdateClient->updateQuery(); - + // An error occurred above. + // Therefore, the operation did not proceed any further. + // Set this object active for asynchronous error handling. + SetActive(); + + // Now, that everything is ready, just inform the active scheduler + // that operation is finished. Pass the error code for the observer. + TRequestStatus* status( &iStatus ); + User::RequestComplete( status, error ); + } IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::UpdateQuery() end"); } +// ----------------------------------------------------------------------------- +// CIAUpdateManager::DoCancel +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::DoCancel() + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::DoCancel() begin"); + UpdateClient().CancelAsyncRequest(); + // Reset result values because we are starting a new operation. + ResetResults(); + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::DoCancel() end"); + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::RunL +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::RunL() + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::RunL() begin"); + // Update operation error code + TInt errorCode( iStatus.Int() ); + IAUPDATE_TRACE_1("[IAUPDATE] error code: %d", errorCode ); + if ( errorCode == KErrServerTerminated ) + { + // Handle is released if server is terminated + UpdateClient().Close(); + } + + // Variables for operation and result information. + TIAUpdateType updateType( UpdateType() ); + IAUPDATE_TRACE_1("[IAUPDATE] update type: %d", updateType ); + CIAUpdateResult* updateResult( NULL ); + + if ( updateType == EIAUpdateUpdate ) + { + // Update result object is required. + // Notice that the ownership is transferred later. + // So, this function does not need to delete updateResult object. + TRAPD( trapError, updateResult = CIAUpdateResult::NewL() ); + if ( updateResult ) + { + updateResult->SetSuccessCount( iSuccessCount ); + updateResult->SetFailCount( iFailCount ); + updateResult->SetCancelCount( iCancelCount ); + } + else + { + // Something went wrong when creating update result object. + // Update the error code accordingly. + errorCode = trapError; + } + // Let's assume that connection is not needed anymore + UpdateClient().Close(); + } + + + // Inform that no operation is going on anymore. + // This is required for busy check. + SetUpdateType( EIAUpdateIdle ); + + // Use the update type of the ongoing operation to check what callback + // function to call. + switch ( updateType ) + { + case EIAUpdateStartServer: + if ( errorCode == KErrNone ) + { + CheckUpdatesContinue(); + } + else + { + UpdateClient().Close(); + Observer().CheckUpdatesComplete( errorCode, 0); + } + break; + + case EIAUpdateCheck: + if ( iSuccessCount == 0 ) + { + // Let's assume that connection is not needed anymore + UpdateClient().Close(); + } + IAUPDATE_TRACE_1("[IAUPDATE] success count: %d", iSuccessCount ); + Observer().CheckUpdatesComplete( errorCode, iSuccessCount ); + break; + + case EIAUpdateUpdate: + // Notice that ownership of result object is transferred here. + IAUPDATE_TRACE_3("[IAUPDATE] success count: %d failed count: %d cancelled count: %d", iSuccessCount, iFailCount, iCancelCount ); + Observer().UpdateComplete( errorCode, updateResult ); + break; + + case EIAUpdateQuery: + if ( !iUpdateNow ) + { + // Let's assume that connection is not needed anymore + UpdateClient().Close(); + } + IAUPDATE_TRACE_1("[IAUPDATE] update now: %d", iUpdateNow ); + Observer().UpdateQueryComplete( errorCode, iUpdateNow ); + break; + + default: + // Should not ever come here. + break; + } + + // Do not anything else than return after callback function is called because + // this instance can be deleted by a client in a callback function + // + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::RunL() end"); + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::ResetResults +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::ResetResults() + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::ResetResults() begin"); + // Set the member variables to their default values. + iSuccessCount = 0; + iFailCount = 0; + iCancelCount = 0; + iUpdateNow = EFalse; + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::ResetResults() end"); + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::BusyCheck +// +// ----------------------------------------------------------------------------- +// +TBool CIAUpdateManager::BusyCheck() const + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::BusyCheck()"); + if ( UpdateType() == EIAUpdateIdle ) + { + return EFalse; + } + else + { + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::UpdateClient +// +// ----------------------------------------------------------------------------- +// +RIAUpdateClient& CIAUpdateManager::UpdateClient() + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::UpdateClient()"); + return iUpdateClient; + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::Observer +// +// ----------------------------------------------------------------------------- +// +MIAUpdateObserver& CIAUpdateManager::Observer() const + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::Observer()"); + return iObserver; + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::UpdateType +// +// ----------------------------------------------------------------------------- +// +CIAUpdateManager::TIAUpdateType CIAUpdateManager::UpdateType() const + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::UpdateType()"); + return iUpdateType; + } + + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::SetUpdateType +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::SetUpdateType( CIAUpdateManager::TIAUpdateType aUpdateType ) + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::SetUpdateType() begin"); + IAUPDATE_TRACE_1("[IAUPDATE] update type: %d", aUpdateType ); + iUpdateType = aUpdateType; + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::SetUpdateType() end"); + } + // ----------------------------------------------------------------------------- // CIAUpdateManager::HandleGainingForeground // iaupdate.exe is brought to foreground if visible request is ongoing @@ -167,7 +524,7 @@ void CIAUpdateManager::HandleGainingForeground() { IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::HandleGainingForeground() begin"); - //iUpdateClient->broughtToForeground(); + iUpdateClient.BroughtToForeground(); IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::HandleGainingForeground() end"); } @@ -180,8 +537,71 @@ { } +// ----------------------------------------------------------------------------- +// CIAUpdateManager::CheckUpdatesContinue +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::CheckUpdatesContinue() + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CheckUpdatesContinue() begin"); + TInt error = KErrNone; + SetUpdateType( EIAUpdateCheck ); + error = UpdateClient().ConnectToApp(); + if ( error == KErrNone ) + { + error = UpdateClient().CheckUpdates( *iUpdateParameters, + iSuccessCount, + iStatus ); + } + + if ( error == KErrNone ) + { + // Set this object active. + // Because everything went ok, + // the operation will be handled asynchronously + // and the service provider will inform us when the operation + // is finished. + SetActive(); + } + else + { + // Because we are going to activate this active object, + // set the status pending. + iStatus = KRequestPending; + + // An error occurred above. + // Therefore, the operation did not proceed any further. + // Set this object active for asynchronous error handling. + SetActive(); + + // Now, that everything is ready, just inform the active scheduler + // that operation is finished. Pass the error code for the observer. + TRequestStatus* status( &iStatus ); + User::RequestComplete( status, error ); + } + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CheckUpdatesContinue() end"); + } + +// ----------------------------------------------------------------------------- +// CIAUpdateManager::CopyUpdateParamsL +// +// ----------------------------------------------------------------------------- +// +void CIAUpdateManager::CopyUpdateParamsL( const CIAUpdateParameters& aUpdateParameters ) + { + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CopyUpdateParamsL() begin"); + iUpdateParameters = CIAUpdateParameters::NewL(); + iUpdateParameters->SetCommandLineArgumentsL( aUpdateParameters.CommandLineArguments() ); + iUpdateParameters->SetCommandLineExecutableL( aUpdateParameters.CommandLineExecutable() ); + iUpdateParameters->SetImportance( aUpdateParameters.Importance() ); + iUpdateParameters->SetRefresh( aUpdateParameters.Refresh() ); + iUpdateParameters->SetSearchCriteriaL( aUpdateParameters.SearchCriteria() ); + iUpdateParameters->SetShowProgress( aUpdateParameters.ShowProgress() ); + iUpdateParameters->SetType( aUpdateParameters.Type() ); + iUpdateParameters->SetUid( aUpdateParameters.Uid() ); + IAUPDATE_TRACE("[IAUPDATE] CIAUpdateManager::CopyUpdateParamsL() end"); + } - -