diff -r f40128debb5d -r e0d6e9bd3ca7 javamanager/javabackup/midp2backup_usif/src.s60/midp2backupplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javamanager/javabackup/midp2backup_usif/src.s60/midp2backupplugin.cpp Tue Jul 06 14:10:26 2010 +0300 @@ -0,0 +1,637 @@ +/* +* Copyright (c) 2008-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: Implementation of Midp2BackupPlugin +* +*/ + + +#include "midp2backupplugin.h" +#include "midp2backupdataids.h" +#include "apparcbackuputil.h" +#include "javastoragebackuputil.h" +#include "javaversionbackuputil.h" + +#include "javastoragenames.h" +#include "javastorageentry.h" +#include "javastorage.h" + +#include "javacommonutils.h" +#include "logger.h" + +#include +#include +#include +#include +#include + + +using namespace std; +using namespace java::storage; +using namespace java::backup; + +// ======== MEMBER FUNCTIONS ======== + +CMidp2BackupPlugin::CMidp2BackupPlugin() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin constructor"); +} + +void CMidp2BackupPlugin::ConstructL() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ConstructL"); + + iIconDescIndex = 0; + iBufferSpaceLeft = 0; + iFirstCallToGetBackupDataSection = ETrue; + iStorageDataBackup = ETrue; + iStorageDataRestore = ETrue; + iJavaVersionInfoWritten = EFalse; + iRestoreState = EVersion; + + User::LeaveIfError(iFs.Connect()); + // to share file handles with AppArc + User::LeaveIfError(iFs.ShareProtected()); + + iStorageBackupUtil = CStorageBackupUtil::NewL(); + iAppArcUtil = CAppArcBackupUtil::NewL(iFs); +} + +CMidp2BackupPlugin* CMidp2BackupPlugin::NewL() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::NewL"); + + CMidp2BackupPlugin* self = new(ELeave) CMidp2BackupPlugin(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + + return self; +} + +CMidp2BackupPlugin::~CMidp2BackupPlugin() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin destructor"); + + iFs.Close(); + iIconUidArray.Close(); + delete iAppArcUtil; + delete iIconDesc; + delete iRestoreIconDesc; + delete iStorageBackupUtil; +} + +// from base class CBackupPlugin + +void CMidp2BackupPlugin::PrepareForBURL(TInt aBackupStateValue) +{ + (void)aBackupStateValue; // Just to suppress a warning in release builds + LOG1(EBackup, EInfo, "CMidp2BackupPlugin::PrepareForBURL, BUR state: %d", aBackupStateValue); +} + +void CMidp2BackupPlugin::ReceiveSnapshotDataL(TDriveNumber /* aDrive */, TDesC8& /* aBuffer */, TBool /* aLastSection */) +{ + JELOG2(EBackup); + User::Leave(KErrNotSupported); +} + +TUint CMidp2BackupPlugin::GetExpectedDataSize(TDriveNumber /* aDrive */) +{ + JELOG2(EBackup); + return 0; +} + +void CMidp2BackupPlugin::GetSnapshotDataL(TDriveNumber /* aDrive */, TPtr8& /* aBuffer */, TBool& /* aFinished */) +{ + JELOG2(EBackup); + User::Leave(KErrNotSupported); +} + +void CMidp2BackupPlugin::InitialiseGetBackupDataL(TDriveNumber aDrive) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::InitialiseGetBackupDataL"); + iDrive = aDrive; +} + +void CMidp2BackupPlugin::GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::GetBackupDataSectionL"); + + iBufferSpaceLeft = aBuffer.MaxLength(); + RDesWriteStream stream(aBuffer); + CleanupClosePushL(stream); + + if (!iJavaVersionInfoWritten) + { + JavaVersionBackupUtil::WriteJavaVersionL(stream); + iJavaVersionInfoWritten = ETrue; + iBufferSpaceLeft -= 8; + } + + if (iStorageDataBackup) + { + iStorageBackupUtil->BackupStorageDataL(stream, iStorageDataBackup, iBufferSpaceLeft); + aFinished = EFalse; + } + + else + { + if (iFirstCallToGetBackupDataSection) + { + LOG(EBackup, EInfo, "First Call To GetBackupDataSection"); + // Get the uids of midlets whose icons are to be backed up + iIconFilePointer = 0; + ResetIconArray(); + iAppArcUtil->GetMidletsFromAppArcL(iIconUidArray, iDrive); + + /* Streaming MMC's unique Id, if current drive is MMC + and there's at least one midlet on the drive*/ + if (iIconUidArray.Count() > 0 && iDrive >= EDriveE && iDrive <= EDriveZ) + { + TUint32 mmcId = MmcIdL(); + + if (mmcId != 0) + { + LOG1(EBackup,EInfo, "Write MMC id: %u", mmcId); + stream.WriteUint32L(mmcId); + iBufferSpaceLeft -= sizeof(mmcId); + } + } + // Setting flag to EFalse + iFirstCallToGetBackupDataSection = EFalse; + } + + // Next icon uid and filename + TUid currentUid; + HBufC* fullFileName = NULL; + + // Streaming leftover part of icon file + if (iIconDescIndex) + { + LOG(EBackup, EInfo, "Streaming leftover part of icon file"); + + /* if the icon file is bigger than the space in the buffer, write only + part of it and fill iLeftover with remaining part. */ + if (iIconDesc->Size() - iIconDescIndex > iBufferSpaceLeft) + { + stream.WriteL(iIconDesc->Mid(iIconDescIndex), iBufferSpaceLeft); + iIconDescIndex += iBufferSpaceLeft; + } + else + { + stream.WriteL(iIconDesc->Mid(iIconDescIndex)); + iIconDescIndex = 0; + } + + aFinished = EFalse; + } + + // Get new icon file + else if (NextIcon(currentUid, fullFileName)) + { + LOG1(EBackup, EInfo, "New icon file, id: %d", currentUid.iUid); + + // Readstream for icon file + RFileReadStream fileStream; + + User::LeaveIfError(fileStream.Open(iFs, *fullFileName, EFileRead)); + CleanupClosePushL(fileStream); + + TEntry* entry = new(ELeave) TEntry(); + CleanupStack::PushL(entry); + + iFs.Entry(*fullFileName, *entry); + TInt32 size = entry->iSize; + + // Write icon file content into iIconDesc + LOG(EBackup, EInfo, "Write icon file content into iIconDesc"); + delete iIconDesc; + iIconDesc = NULL; + iIconDesc = HBufC8::NewL(size); + + TPtr8 buf = iIconDesc->Des(); + fileStream.ReadL(buf, size); + + // get the group name of the midlet from AppArc + TBuf< KApaMaxAppGroupName >groupName(iAppArcUtil->GetMidletGroupName(currentUid)); + TInt groupNameSize = groupName.Size(); + + // Write the size of the data + LOG(EBackup,EInfo, "Write the size of the data"); + + TParsePtrC parse(*fullFileName); + TPtrC fileName = parse.NameAndExt(); + TInt32 fileNameSize = fileName.Size(); + + stream.WriteInt32L(sizeof(TUid) // Uid + + sizeof(TInt32) // fileNameSize + + fileNameSize // filename + + sizeof(TInt32) // number of icons + + sizeof(TInt32) // groupnamesize + + groupNameSize + + size // icon file + ); + iBufferSpaceLeft -= sizeof(TInt32); + + // Write the Uid of the midlet + LOG(EBackup, EInfo, "Write the Uid of the midlet"); + stream.WriteInt32L(currentUid.iUid); + iBufferSpaceLeft -= sizeof(TUid); + + // Write the size of the icon filename + LOG(EBackup, EInfo, "Write the size of the icon filename"); + stream.WriteInt32L(fileNameSize); + iBufferSpaceLeft -= sizeof(TInt32); + + // Write icon filename + LOG(EBackup, EInfo, "Write icon filename"); + stream.WriteL(fileName); + iBufferSpaceLeft -= fileNameSize; + + // Write number of icons in midlet + LOG(EBackup, EInfo, "Write number of icons in midlet"); + TInt iconCount; + iAppArcUtil->NumberOfOwnDefinedIcons(TUid::Uid(currentUid.iUid), iconCount); + stream.WriteInt32L(iconCount); + iBufferSpaceLeft -= sizeof(TInt32); + + // TPtr8 groupName(iAppArcUtil->GetMidletGroupName(currentUid)); + LOG(EBackup, EInfo, "Write the size of the Group name of the midlet"); + stream.WriteInt32L(groupNameSize); + iBufferSpaceLeft -= sizeof(TInt32); + + if (groupNameSize != 0) + { + LOG(EBackup, EInfo, "Write the Group name of the midlet"); + stream.WriteL(groupName); + iBufferSpaceLeft -= groupNameSize; + } + + /* if the icon file is bigger than the space in the buffer, + write only part of it and fill iLeftover with remaining part */ + LOG(EBackup, EInfo, "Write icon"); + if (size > iBufferSpaceLeft) + { + stream.WriteL(buf, iBufferSpaceLeft); + iIconDescIndex = iBufferSpaceLeft; + } + else + { + stream.WriteL(buf, size); + iIconDescIndex = 0; + } + + aFinished = EFalse; + + CleanupStack::PopAndDestroy(&fileStream); + CleanupStack::PopAndDestroy(entry); + } + + else + { + aFinished = ETrue; + iFirstCallToGetBackupDataSection = ETrue; + iStorageDataBackup = ETrue; + } + + delete fullFileName; + } + CleanupStack::PopAndDestroy(&stream); +} + + +void CMidp2BackupPlugin::InitialiseRestoreBaseDataL(TDriveNumber aDrive) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::InitialiseRestoreBaseDataL"); + iDrive = aDrive; +} + +void CMidp2BackupPlugin::RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::RestoreBaseDataSectionL"); + + iBufferSpaceLeft = aBuffer.Size(); + RDesReadStream stream(aBuffer); + CleanupClosePushL(stream); + TBool versionCheck = ETrue; + + if (((iRestoreState == EVersion) || (iRestoreState == EInstall)) && iBufferSpaceLeft >= 8) + { + if (iRestoreState == EInstall) + { + versionCheck = EFalse; + } + TUint ret = JavaVersionBackupUtil::CheckJavaVersionL(stream,iDrive,versionCheck); + if (1==ret) + { + // Here set the satus to restore finished, so that control goes back to SBE & SBE calls B&R for another drive + iRestoreState = EInstall; + } + else + { + /* version information has been written to stream. + So change restore state to restore storage data */ + iRestoreState = EStorage; + } + // version information is of length 8 bytes. + iBufferSpaceLeft -= 8; + } + + if (iRestoreState == EStorage) + { + iStorageBackupUtil -> RestoreStorageDataL(stream, iRestoreState, iBufferSpaceLeft); + } + + // Only at first call + if ((iRestoreState != EStorage && iRestoreState != EVersion) && (iRestoreState != EInstall)) + { + if (iRestoreState == EAppArc) + { + // Making AppArc deregistrations + TRAPD(err, iAppArcUtil->DeregisterAppsL(iDrive)); + + if (err) + { + ELOG(EBackup, "Leave in deregistering apps"); + } + } + + // Process the data buffer for restore + ProcessBufferL(stream); + + if (aFinished) + { + // Set state to EStorage + iRestoreState = EStorage; + } + } + + aFinished = ETrue; + CleanupStack::PopAndDestroy(&stream); +} + +void CMidp2BackupPlugin::InitialiseRestoreIncrementDataL(TDriveNumber /* aDrive */) +{ + JELOG2(EBackup); + User::Leave(KErrNotSupported); +} + +void CMidp2BackupPlugin::RestoreIncrementDataSectionL(TDesC8& /* aBuffer */, TBool /* aFinished */) +{ + JELOG2(EBackup); + User::Leave(KErrNotSupported); +} + +void CMidp2BackupPlugin::RestoreComplete(TDriveNumber /* aDrive */) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::RestoreComplete"); +} + +TUint CMidp2BackupPlugin::MmcIdL() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::MmcIdL()"); + + TVolumeInfo* volumeInfo = new(ELeave) TVolumeInfo(); + + TInt err = iFs.Volume(*volumeInfo, iDrive); + + if (!err) + { + TUint mmcId = volumeInfo->iUniqueID; + return mmcId; + } + else + { + return 0; + } + + +} + +void CMidp2BackupPlugin::ProcessBufferL(RDesReadStream& stream) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ProcessBuffer()"); + + // Cycle until there's data in the buffer + while (iBufferSpaceLeft > 0) + { + switch (iRestoreState) + { + case EAppArc: + ProcessFirstBufferL(stream, iBufferSpaceLeft); + break; + + case EInIcon: + ProcessInIconL(stream, iBufferSpaceLeft); + break; + + case EInSize: + ProcessInSizeL(stream, iBufferSpaceLeft); + break; + + default: + CleanupStack::PopAndDestroy(&stream); + User::Leave(KErrNotSupported); + } + } +} + + +_LIT(KStarWildCard, "*.*"); + +void CMidp2BackupPlugin::RestoreMmcRegistryL() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::RestoreMmcRegistry()"); + + /* If backed up MMC is not the same as the current MMC, copy the entries + from the directory of the backed up MMC to the directory + of the current MMC */ + TUint32 mmc = MmcIdL(); + + if (iBackupMmc != mmc) + { + // Create path to old place + TPath path_old; + CreateMmcPath(path_old, iDrive, iBackupMmc); + + // Create path to new place + TPath path_new; + CreateMmcPath(path_new, iDrive, mmc); + + // Get old files list + CFileMan* fileMan = CFileMan::NewL(iFs); + + CleanupStack::PushL(fileMan); + + // Copy to new place + iFs.MkDir(path_new); + path_old.Append(KStarWildCard); + TInt err = fileMan->Copy(path_old, path_new); + + ILOG1(EBackup, "File copy, status: %d", err); + + User::LeaveIfError(err); + + CleanupStack::PopAndDestroy(); + } +} + +_LIT(KPrivatePath, "C:\\private\\"); + +void CMidp2BackupPlugin::CreateMmcPath(TDes& aPathName, TInt aDrive, TUint aUniqueId) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::CreateMmcPath()"); + + aPathName.Zero(); + aPathName.Append(KPrivatePath); + aPathName.AppendNum(KRegistryServerUid, EHex); + aPathName.Append(KPathDelimiter); + + // append drive name + TDriveUnit driveUnit(aDrive); + aPathName.Append(driveUnit.Name().Left(1)); + aPathName.Append(KPathDelimiter); + + TUint64 id = aUniqueId; + aPathName.AppendNum(id, EHex); + aPathName.Append(KPathDelimiter); +} + +TBool CMidp2BackupPlugin::NextIcon(TUid& aCurrentUid, HBufC*& aFullFileName) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::NextIcon()"); + + if (iIconUidArray.Count() > iIconFilePointer) + { + aCurrentUid = iIconUidArray[iIconFilePointer]; + iAppArcUtil->GetIconFilename(iIconUidArray[iIconFilePointer], aFullFileName); + iIconFilePointer++; + return ETrue; + } + else + { + // There are no more icon files + return EFalse; + } +} + +void CMidp2BackupPlugin::ProcessFirstBufferL(RDesReadStream& aStream, TInt& aBufferSpaceLeft) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ProcessFirstBuffer()"); + + if (iDrive >= EDriveE && iDrive <= EDriveZ) + { + // Read MMC id and restore MMC entries if needed + iBackupMmc = aStream.ReadUint32L(); + aBufferSpaceLeft -= sizeof(iBackupMmc); + LOG1(EBackup, EInfo, "Read MMC Id: %u", iBackupMmc); + RestoreMmcRegistryL(); + } + if (aBufferSpaceLeft >= sizeof(TInt32)) + { + iIconFileSizeLeft = aStream.ReadInt32L(); + aBufferSpaceLeft -= sizeof(iIconFileSizeLeft); + iRestoreIconDesc = HBufC8::NewL(iIconFileSizeLeft); + iRestoreState = EInIcon; + } + else + { + // No more data to read + aBufferSpaceLeft = 0; + } +} + +void CMidp2BackupPlugin::ProcessInIconL(RDesReadStream& aStream, TInt& aBufferSpaceLeft) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ProcessInIcon()"); + + TPtr8 restoreIconPtr = iRestoreIconDesc->Des(); + HBufC8* tempDesc = HBufC8::NewL(iIconFileSizeLeft); + CleanupStack::PushL(tempDesc); + TPtr8 tempPtr = tempDesc->Des(); + + // Icon cannot be read fully + if (iIconFileSizeLeft > aBufferSpaceLeft) + { + aStream.ReadL(tempPtr, aBufferSpaceLeft); + restoreIconPtr.Append(tempPtr); + iIconFileSizeLeft -= aBufferSpaceLeft; + aBufferSpaceLeft = 0; + iRestoreState = EInIcon; + } + // Icon can be read fully + else + { + aStream.ReadL(tempPtr, iIconFileSizeLeft); + restoreIconPtr.Append(tempPtr); + aBufferSpaceLeft -= iIconFileSizeLeft; + iRestoreState = EInSize; + + TRAPD(err, iAppArcUtil->RegisterAppL(restoreIconPtr, iDrive)); + + if (err) + { + ELOG(EBackup, "Registerin application to AppArc failed."); + } + } + + CleanupStack::PopAndDestroy(tempDesc); +} + +void CMidp2BackupPlugin::ProcessInSizeL(RDesReadStream& aStream, TInt& aBufferSpaceLeft) +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ProcessInSize()"); + + if (aBufferSpaceLeft >= sizeof(TInt32)) + { + if (iSizeBuffer.Size() != 0) + { + // Read leftover part of size + TInt readData = sizeof(TInt32) - iSizeBuffer.Size(); + aStream.ReadL(iSizeBuffer, readData); + RMemReadStream sizeStream(iSizeBuffer.Ptr(), 4); + CleanupClosePushL(sizeStream); + iIconFileSizeLeft = sizeStream.ReadInt32L(); + CleanupStack::PopAndDestroy(&sizeStream); + aBufferSpaceLeft -= sizeof(readData); + } + else + { + // Read size in full + iIconFileSizeLeft = aStream.ReadInt32L(); + aBufferSpaceLeft -= sizeof(iIconFileSizeLeft); + } + + delete iRestoreIconDesc; + iRestoreIconDesc = NULL; + iRestoreIconDesc = HBufC8::NewL(iIconFileSizeLeft); + iRestoreState = EInIcon; + } + else + { + // Read first byte(s) of size + aStream.ReadL(iSizeBuffer, aBufferSpaceLeft); + aBufferSpaceLeft = 0; + } +} + +void CMidp2BackupPlugin::ResetIconArray() +{ + LOG(EBackup, EInfo, "CMidp2BackupPlugin::ResetIconArray()"); + + // Remove all entries + while (iIconUidArray.Count()) + { + iIconUidArray.Remove(0); + } +}