--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javamanager/javabackup/midp2backup/src.s60/midp2backupplugin.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,643 @@
+/*
+* 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 <sbdefs.h>
+#include <s32mem.h>
+#include <s32file.h>
+#include <f32file.h>
+#include <apgcli.h>
+
+
+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);
+
+ TDesC path_old_Des(path_old);
+ TDesC path_new_Des(path_new);
+
+ /*LOG1WSTR( EBackup, EInfo, "path_old: %S", &path_old );
+ LOG1WSTR( EBackup, EInfo, "path_new: %S", &path_new );
+ */
+ 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);
+ }
+}