/*
* Copyright (c) 2006-2008 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: Contains CNcdNodeInstallProxy class implementation
*
*/
#include <bamdesca.h>
#include <bautils.h>
#include <s32mem.h>
#include "ncdnodeinstallproxy.h"
#include "ncdnodeproxy.h"
#include "ncdnodemetadataproxy.h"
#include "ncdproviderproxy.h"
#include "ncdnodemanagerproxy.h"
#include "ncdserverreportmanagerproxy.h"
#include "ncdoperationimpl.h"
#include "ncdinstalloperationproxy.h"
#include "ncdsilentinstalloperationproxy.h"
#include "ncdoperationmanagerproxy.h"
#include "ncdoperationdatatypes.h"
#include "catalogsclientserver.h"
#include "ncdnodeidentifier.h"
#include "ncdnodefunctionids.h"
#include "ncdnodeclassids.h"
#include "catalogsinterfaceidentifier.h"
#include "catalogsutils.h"
#include "catalogsdebug.h"
#include "ncdpanics.h"
#include "catalogsconstants.h"
#include "ncdinstallinfo.h"
#include "ncdfileinfo.h"
#include "ncdinstallationservice.h"
#include "ncddeviceinteractionfactory.h"
#include "ncdinstalledapplicationimpl.h"
#include "ncdinstalledthemeimpl.h"
#include "ncdinstalledfileimpl.h"
#include "ncdinstalledcontent.h"
#include "ncderrors.h"
#include "ncdextendedinstallinfo.h"
#include "ncdnodedownloadproxy.h"
// ======== PUBLIC MEMBER FUNCTIONS ========
CNcdNodeInstallProxy::CNcdNodeInstallProxy(
MCatalogsClientServer& aSession,
TInt aHandle,
CNcdNodeMetadataProxy& aMetadata )
: CNcdInterfaceBaseProxy( aSession, aHandle, &aMetadata ),
iMetadata( aMetadata )
{
}
void CNcdNodeInstallProxy::ConstructL()
{
// Register the interface
MNcdNodeInstall* interface( this );
AddInterfaceL(
CCatalogsInterfaceIdentifier::NewL( interface, this,
MNcdNodeInstall::KInterfaceUid ) );
iInstallationService =
&Metadata().Node().OperationManager().InstallationServiceL();
InternalizeL();
}
CNcdNodeInstallProxy* CNcdNodeInstallProxy::NewL(
MCatalogsClientServer& aSession,
TInt aHandle,
CNcdNodeMetadataProxy& aMetadata )
{
CNcdNodeInstallProxy* self =
CNcdNodeInstallProxy::NewLC( aSession, aHandle, aMetadata );
CleanupStack::Pop( self );
return self;
}
CNcdNodeInstallProxy* CNcdNodeInstallProxy::NewLC(
MCatalogsClientServer& aSession,
TInt aHandle,
CNcdNodeMetadataProxy& aMetadata )
{
CNcdNodeInstallProxy* self =
new( ELeave ) CNcdNodeInstallProxy( aSession, aHandle, aMetadata );
// Using PushL because the object does not have any references yet
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
CNcdNodeInstallProxy::~CNcdNodeInstallProxy()
{
DLTRACEIN((""));
// Remove interfaces implemented by this class from the interface list.
// So, the interface list is up to date when this class object is deleted.
RemoveInterface( MNcdNodeInstall::KInterfaceUid );
// Delete member variables here
// Do not delete installation service, node and operation manager because
// this object does not own them.
// Release all content objects
iContent.ResetAndDestroy();
}
CNcdNodeMetadataProxy& CNcdNodeInstallProxy::Metadata() const
{
return iMetadata;
}
void CNcdNodeInstallProxy::InternalizeL()
{
DLTRACEIN((""));
HBufC8* data( NULL );
// Because we do not know the exact size of the data, use
// the alloc method, which creates the buffer of the right size
// and sets the pointer to point to the created buffer.
// Get all the data that is necessary to internalize this object
// from the server side.
User::LeaveIfError(
ClientServerSession().
SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalize,
KNullDesC8,
data,
Handle(),
0 ) );
if ( data == NULL )
{
DLERROR((""));
User::Leave( KErrNotFound );
}
CleanupStack::PushL( data );
// Read the data from the stream and insert it to the member variables
RDesReadStream stream( *data );
CleanupClosePushL( stream );
InternalizeDataL( stream );
// Closes the stream
CleanupStack::PopAndDestroy( &stream );
CleanupStack::PopAndDestroy( data );
DLTRACEOUT((""));
}
// ---------------------------------------------------------------------------
// Checks if this item has the purpose
// ---------------------------------------------------------------------------
//
TBool CNcdNodeInstallProxy::IsPurpose( TNcdItemPurpose aPurpose ) const
{
return iPurpose & aPurpose;
}
// MNcdNodeInstall functions
// ---------------------------------------------------------------------------
// Creates an install operation
// ---------------------------------------------------------------------------
//
MNcdInstallOperation* CNcdNodeInstallProxy::InstallL(
MNcdInstallOperationObserver& aObserver )
{
DLTRACEIN((""));
// Create operation
// Using proxy as the observer. Forwards callbacks to the real operation
// observer
CNcdInstallOperationProxy* op =
Metadata().Node().OperationManager().CreateInstallOperationL(
Metadata().Node(), this );
iOperationObserver = &aObserver;
DLTRACEOUT((""));
return op;
}
// ---------------------------------------------------------------------------
// Creates an install operation
// ---------------------------------------------------------------------------
//
MNcdInstallOperation* CNcdNodeInstallProxy::SilentInstallL(
MNcdInstallOperationObserver& aObserver,
const SwiUI::TInstallOptions& aInstallOptions )
{
DLTRACEIN((""));
// Create operation
// Using proxy as the observer. Forwards callbacks to the real operation
// observer.
// Notice that TrustedUI capabilites are checked when silent install operation is
// created in the server side.
CNcdInstallOperationProxy* op =
Metadata().Node().OperationManager().CreateSilentInstallOperationL(
Metadata().Node(), this, aInstallOptions );
iOperationObserver = &aObserver;
DLTRACEOUT((""));
return op;
}
// ---------------------------------------------------------------------------
// Returns installed status
// ---------------------------------------------------------------------------
//
TBool CNcdNodeInstallProxy::IsInstalledL() const
{
DLTRACEIN((""));
if ( !iInstalled || !iContent.Count() )
{
DLTRACEOUT(("Not installed"));
return EFalse;
}
for ( TInt i = 0; i < iContent.Count(); ++i )
{
if ( !iContent[i]->IsInstalledL() )
{
DLTRACEOUT(("Not installed (entirely)"));
return EFalse;
}
}
DLTRACEOUT(("Installed"));
return ETrue;
}
// ---------------------------------------------------------------------------
// IsLaunchableL
// ---------------------------------------------------------------------------
//
TBool CNcdNodeInstallProxy::IsLaunchable() const
{
DLTRACEIN((""));
for ( TInt i = 0; i < iContent.Count(); ++i )
{
if ( iContent[i]->IsLaunchable() )
{
DLTRACEOUT(("Item contains something launchable"));
return ETrue;
}
}
DLTRACEOUT(("Item doesn't contain anything launchable"));
return EFalse;
}
// ---------------------------------------------------------------------------
// InstalledContentL
// ---------------------------------------------------------------------------
//
RCatalogsArray<MNcdInstalledContent>
CNcdNodeInstallProxy::InstalledContentL()
{
DLTRACEIN(("this-ptr: %x, refcount: %d", this, TotalRefCount() ));
RCatalogsArray<MNcdInstalledContent> array;
CleanupResetAndDestroyPushL( array );
array.ReserveL( iContent.Count() );
MNcdInstalledContent* content = NULL;
for ( TInt i = 0; i < iContent.Count(); ++i )
{
content = iContent[i];
array.AppendL( content );
content->AddRef();
}
CleanupStack::Pop( &array );
DLTRACEOUT(("this-ptr: %x, refcount: %d", this, TotalRefCount() ));
return array;
}
// ---------------------------------------------------------------------------
// SetAsInstalledL
// ---------------------------------------------------------------------------
//
void CNcdNodeInstallProxy::SetApplicationInstalledL( TInt aErrorCode )
{
DLTRACEIN(("error code: %d", aErrorCode));
// This function can only be called if download operation has already been done.
CNcdNodeDownloadProxy* download( Metadata().Download() );
if ( download == NULL
|| !download->IsDownloadedL() )
{
DLINFO(("download has not been done"));
User::Leave( KErrAbort );
}
// Handle the information in the server side.
// This will also delete the content install files if they
// still exist after succesfull installation.
CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
CleanupStack::PushL( buf );
RBufWriteStream stream( *buf );
CleanupClosePushL( stream );
stream.WriteInt32L( aErrorCode );
CleanupStack::PopAndDestroy( &stream );
TPtrC8 ptr = buf->Ptr( 0 );
TInt tmp( 0 );
TInt error =
ClientServerSession().
SendSync( NcdNodeFunctionIds::ENcdSetApplicationInstalled,
ptr,
tmp,
Handle() );
User::LeaveIfError( error );
CleanupStack::PopAndDestroy( buf );
CNcdNodeManagerProxy& nodeManager(
Metadata().Node().NodeManager() );
CNcdProviderProxy& provider(
nodeManager.Provider() );
// Send an error report.
// Report manager is checking if the install report list already contains the
// corresonding report and replaces an old one if necessary. But, in all the
// cases set this report. If install has been set as success or failure,
// always send the information. Even if the node state has been installed before
// this operation, send new report because this may be a new try to install
// the content for some reason. So, success and failure information is necessary
// then also.
provider.ServerReportManager().NodeSetAsInstalledL( Metadata().Node(),
aErrorCode );
// Internalize node and all corresponding nodes.
// This way, all their information will be up-to-date.
// For example, the installation state may have changed because of the
// settings above.
nodeManager.InternalizeRelatedNodesL( Metadata().Node() );
}
// ---------------------------------------------------------------------------
// Installationservice getter
// ---------------------------------------------------------------------------
//
MNcdInstallationService& CNcdNodeInstallProxy::InstallationService()
{
return *iInstallationService;
}
// ---------------------------------------------------------------------------
// File session getter
// ---------------------------------------------------------------------------
//
RFs& CNcdNodeInstallProxy::FileSession()
{
return iInstallationService->FileServerSession();
}
// ---------------------------------------------------------------------------
// File opener
// ---------------------------------------------------------------------------
//
RFile CNcdNodeInstallProxy::OpenFileL( TInt aFileIndex )
{
DLTRACEIN((""));
// Convert index to a descriptor
HBufC8* filenumber = IntToDes8LC( aFileIndex );
RFile fileHandle = ClientServerSession().SendSyncFileOpenL(
NcdNodeFunctionIds::ENcdInstallOpenFile,
*filenumber,
Handle() );
CleanupStack::PopAndDestroy( filenumber );
DLTRACEOUT((""));
return fileHandle;
}
// ---------------------------------------------------------------------------
// Handles progress information
// ---------------------------------------------------------------------------
//
void CNcdNodeInstallProxy::InstallProgress( MNcdInstallOperation& aOperation,
TNcdProgress aProgress )
{
DLTRACEIN((""));
DASSERT( iOperationObserver );
iOperationObserver->InstallProgress( aOperation, aProgress );
DLTRACEOUT((""));
}
// ---------------------------------------------------------------------------
// Handles querys
// ---------------------------------------------------------------------------
//
void CNcdNodeInstallProxy::QueryReceived( MNcdInstallOperation& aOperation,
MNcdQuery* aQuery )
{
DLTRACEIN((""));
DASSERT( iOperationObserver );
iOperationObserver->QueryReceived( aOperation, aQuery );
DLTRACEOUT((""));
}
// ---------------------------------------------------------------------------
// Handles operation complete callbacks
// ---------------------------------------------------------------------------
//
void CNcdNodeInstallProxy::OperationComplete(
MNcdInstallOperation& aOperation, TInt aError )
{
DLTRACEIN(( "Error: %d", aError ));
DASSERT( iOperationObserver );
if ( aError == KErrNone || aError == KNcdThemeReinstalled )
{
// update proxy's status from the server
TRAPD( err, iMetadata.InternalizeL() );
if ( err != KErrNone )
{
DLERROR(("Error during internalization: %d", err));
aError = err;
}
}
iOperationObserver->OperationComplete( aOperation, aError );
DLTRACEOUT((""));
}
// Other functions
void CNcdNodeInstallProxy::InternalizeDataL( RReadStream& aStream )
{
DLTRACEIN((""));
// Use catalogsutils.h functions to internalize
// memebervariables according to the data received
// from the server.
// Make sure that the variables are set here in the same
// order as they are externalized in the server side.
// Small mistake here messes up everything!
// First read the class id. Because, it is the first thing in the stream.
TInt classId( aStream.ReadInt32L() );
if ( classId != NcdNodeClassIds::ENcdNodeInstallClassId )
{
// classId is not recognized
DLERROR(("Class id was not recognized!"));
// For testing purposes assert here
DASSERT( EFalse );
// Otherwise leave is adequate
User::Leave( KErrCorrupt );
}
iPurpose = aStream.ReadInt32L();
DLINFO(("Purpose: %u", iPurpose));
iInstalled = aStream.ReadInt32L();
DLINFO(("Installed: %d", iInstalled));
iLaunchable = aStream.ReadInt32L();
DLINFO(("Launchable: %d", iLaunchable));
iContent.ResetAndDestroy();
if ( iInstalled )
{
DLTRACE(("Reading infos"));
TInt infos = aStream.ReadInt32L();
TInt fileIndex = 0;
CNcdExtendedInstallInfo* tempInfo = NULL;
while ( infos )
{
tempInfo = CNcdExtendedInstallInfo::NewLC();
tempInfo->InternalizeL( aStream );
CreateInstalledContentL( *tempInfo, fileIndex );
CleanupStack::PopAndDestroy( tempInfo );
tempInfo = NULL;
--infos;
++fileIndex;
}
}
DLTRACEOUT((""));
}
void CNcdNodeInstallProxy::CreateInstalledContentL(
const CNcdExtendedInstallInfo& aInfo,
TInt aFileIndex )
{
DLTRACEIN((""));
CNcdInstalledContent* content = NULL;
if ( aInfo.Filename() != KNullDesC() )
{
DLTRACE(( _L("Installed file: %S"), &aInfo.Filename() ));
CNcdFileInfo* fileInfo = CNcdFileInfo::NewLC(
aInfo.Filename(), aInfo.MimeType() );
CleanupStack::Pop( fileInfo );
// fileInfo is deleted in CNcdInstalledFile if NewLC leaves
CNcdInstalledFile* file =
CNcdInstalledFile::NewLC( *this, fileInfo, aFileIndex );
content = file;
}
else if ( aInfo.ApplicationUid() != TUid::Null() )
{
DLTRACE(("Application"));
CNcdInstalledApplication* app =
CNcdInstalledApplication::NewLC(
*this,
aInfo.ApplicationUid(),
aInfo.ApplicationVersion(),
aInfo.Parameter(),
aInfo.ContentType(),
aInfo.UriExists() );
content = app;
}
else // assume theme
{
DLTRACE(( _L("Theme: %S"), &aInfo.ThemeName() ));
CNcdInstalledTheme* theme = CNcdInstalledTheme::NewLC(
*this, aInfo.ThemeName().AllocL() );
content = theme;
}
DASSERT( content );
content->AddRef();
content->SetLaunchable( aInfo.IsLaunchable() );
DLTRACE(("Content refcount: %d", content->RefCount() ));
iContent.AppendL( content );
CleanupStack::Pop(); // file, app or theme
DLTRACEOUT(("Content added successfully"));
}