// backup_child.cpp
//
// Copyright (c) 2008 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//
#include <e32property.h>
#include <connect/sbdefs.h>
#include <baBackup.h>
#include "backup.h"
_LIT(KBackupOp, "-b");
_LIT(KRestoreOp, "-r");
const TInt KIdleTime = 5000000; // microseconds
using namespace conn;
class CBackupAO : public CActive
{
public:
static CBackupAO* NewL();
~CBackupAO();
void Start();
private:
CBackupAO();
void ConstructL();
void CheckForRestoreFlagL();
// from CActive
void DoCancel();
void RunL();
private:
CBaBackupSessionWrapper* iBackupSession;
RSemaphore iSem;
TBool iRestoreOp;
};
CBackupAO* CBackupAO::NewL()
{
CBackupAO* self = new (ELeave) CBackupAO();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CBackupAO::CBackupAO():
CActive(CActive::EPriorityStandard)
{
CActiveScheduler::Add(this);
}
CBackupAO::~CBackupAO()
{
Cancel();
delete iBackupSession; // will also issue the ETakeLock to system apps
if (iSem.Handle() > 0)
iSem.Close();
}
void CBackupAO::ConstructL()
{
iBackupSession = CBaBackupSessionWrapper::NewL();
User::LeaveIfError(iSem.CreateGlobal(KBackupSemaphore, 0, EOwnerProcess));
CheckForRestoreFlagL();
}
void CBackupAO::Start()
{
iBackupSession->CloseAll(MBackupObserver::EReleaseLockNoAccess, iStatus);
SetActive();
}
void CBackupAO::RunL()
{
TInt error = iStatus.Int();
// check which instruction we must send
conn::TBURPartType instruction = conn::EBURBackupFull;
if (iRestoreOp)
instruction = conn::EBURRestoreFull;
// inform subscribed parties of our intentions
RProperty bk;
if (error == KErrNone)
error = bk.Set(KUidSystemCategory, KUidBackupRestoreKey, instruction);
// block for a little while to give apps a chance to process the backup instruction
User::After(KIdleTime);
// inform fshell's backup cmd we've put the system into backup-mode (or not!)
RProcess().Rendezvous(error);
if (error == KErrNone)
{
iSem.Wait(); // wait for signal from fshell's backup cmd that we're ok to terminate
bk.Set(KUidSystemCategory, KUidBackupRestoreKey, conn::EBURNormal); // ignore the error in this case. what else can I do?
}
// the process has done it's thing
CActiveScheduler::Stop();
}
void CBackupAO::DoCancel()
{
ASSERT(iBackupSession);
iBackupSession->RestartAll();
}
//
// CBackupAO::CheckForRestoreFlagL
// determine whether we're issuing a backup or a restore
//
void CBackupAO::CheckForRestoreFlagL()
{
HBufC *buffer = HBufC::NewL(User::CommandLineLength());
CleanupStack::PushL(buffer);
TPtr cmdline = buffer->Des();
User::CommandLine(cmdline);
const TInt bPos = cmdline.Find(KBackupOp);
const TInt rPos = cmdline.Find(KRestoreOp);
CleanupStack::PopAndDestroy(1);
if (bPos != KErrNotFound)
{
if (rPos != KErrNotFound)
User::Leave(KErrArgument);
iRestoreOp = EFalse;
return;
}
if (rPos != KErrNotFound)
{
iRestoreOp = ETrue;
return;
}
User::Leave(KErrArgument);
}
static void RunL()
{
// Active Scheduler
CActiveScheduler* s = new(ELeave) CActiveScheduler;
CleanupStack::PushL(s);
CActiveScheduler::Install(s);
CBackupAO* woop = CBackupAO::NewL();
CleanupStack::PushL(woop);
woop->Start();
// start the active scheduler
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(2, s);
}
// program entry-point
TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
TInt err = KErrNoMemory;
if (cleanup)
{
TRAP(err, RunL());
delete cleanup;
}
__UHEAP_MARKEND;
return err;
}