--- a/Symbian3/PDK/Source/GUID-DFF9DFC5-1BE0-5CA2-A2B9-27FA2DECFF59.dita Thu Mar 11 15:24:26 2010 +0000
+++ b/Symbian3/PDK/Source/GUID-DFF9DFC5-1BE0-5CA2-A2B9-27FA2DECFF59.dita Thu Mar 11 18:02:22 2010 +0000
@@ -1,481 +1,481 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
-<!-- This component and the accompanying materials are made available under the terms of the License
-"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:
--->
-<!DOCTYPE task
- PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
-<task id="GUID-DFF9DFC5-1BE0-5CA2-A2B9-27FA2DECFF59" xml:lang="en"><title>Writing
-an Active Backup Client Tutorial</title><shortdesc>A backup client application is often referred to as a data owner
-as it owns the data. This section describes how to write an active backup
-client which works with the Backup Engine and the Backup Server for data backup
-and restore. </shortdesc><prolog><metadata><keywords/></metadata></prolog><taskbody>
-<prereq id="GUID-B83C3258-BE3B-597F-A8EB-5598F059E2E3"><p>Before you start,
-you must understand: </p> <ul>
-<li id="GUID-909ACEA0-363B-585F-AAC7-D85706158930"><p><xref href="GUID-7FDD9FEC-5017-5E5D-A50A-5F343A3C7F6C.dita">Backup
-Engine Concepts</xref> introduce the backup and restore types. </p> </li>
-<li id="GUID-DB7C6BE8-A9A5-592F-BFD2-131FA7139BE2"><p><xref href="GUID-5CA933B9-7987-5DDE-AE12-B0D5AFD31451.dita">Symbian
-Backup and Restore architecture</xref> describes the two ways of data backup
-and restore. </p> </li>
-<li id="GUID-E1A1DC99-39BC-59AD-A2A9-0261D6E689EB"><p><xref href="GUID-937C3D70-2DCC-5084-AC87-3B1E5865A827.dita">Active
-Backup Client Architecture</xref> describes the components involved to do
-active data backup and restore. </p> </li>
-<li id="GUID-1FA3D484-3460-5A81-BD1E-52810746ECD8"><p><xref href="GUID-A81C65CF-CF4E-571C-8080-9D387F46AAD6.dita">Symbian
-Publish and Subscribe</xref> describes how to publish and subscribe events
-using properties. </p> </li>
-</ul> </prereq>
-<context id="GUID-06AB41B7-201A-5EB9-AFF2-1CF231B06118"><p>In an active backup
-and restore, the Backup Engine calls the active backup client to supply the
-data for the backup. Writing an active backup client means to: </p> <ul>
-<li id="GUID-FAAB2D8E-14AD-5866-9D13-26D1DD39EBBC"><p>Create a user defined
-class that has a data member pointer to <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref>. </p> </li>
-<li id="GUID-BB8DB868-66D9-5CE4-8CBD-0D9201365522"><p>Implement the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> interface. </p> </li>
-</ul> </context>
-<steps id="GUID-7D9E4BEE-5BBB-55B1-AB2C-C47E176B0CE7">
-<step id="GUID-95BE7D7F-D355-5CC9-9A02-3351FBC8E709"><cmd/>
-<info>Write an active backup client (data owner) class which must subscribe
-for the <codeph>KUidBackupRestoreKey</codeph> property published by the backup
-server. </info>
-<info>When a backup server receives a request from a client (a host PC) for
-a backup or a restore, it reads backup registration files for a list of data
-owners (refer to step 3). It then calls the <codeph>CSBEClient::SetBURModeL()</codeph> function
-with the registered types (base or incremental, full or partial). This function
-signals start or completion of a backup or restore to all data owners. Data
-owners must subscribe the following publish and subscribe property: </info>
-<substeps id="GUID-29550A41-94C4-5F36-9175-B0FDF2E55483">
-<substep id="GUID-E291A40F-9573-52D7-833D-DDCA3F194B59"><cmd/>
-<info>Key–<codeph>KUidBackupRestoreKey</codeph> defined in the <filepath>epoc32\include\connect\sbdefs.h</filepath> header
-file. This key belongs to the <codeph>KUidSystemCategoryValue</codeph> category. </info>
-</substep>
-<substep id="GUID-774E7565-EB05-5302-B7C7-BD25F6CAFAE0"><cmd/>
-<info>Value–<codeph>TBURPartType</codeph> or <codeph>TBackupIncType</codeph>. </info>
-</substep>
-</substeps>
-<info>The backup client must check the value of the property (flag) on startup,
-in case the device is already in a backup or restore mode. A <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref> object
-can only be created once the publish and subscribe flag has transitioned into
-a backup or restore mode. The backup client can be deleted once the backup
-or restore operation has finished. This releases valuable system resources. </info>
-<info> <codeph>CActiveBackupClient::ConfirmReadyForBURL()</codeph> is called
-to indicate that the backup client is ready for the data supply to the Backup
-Engine. </info>
-<stepxmp><codeblock id="GUID-179BD485-939F-5D89-A123-55FDB8815140" xml:space="preserve">class CReferenceActiveDataOwner : public CActive
- {
- // Methods
-public:
- static CReferenceActiveDataOwner* NewL();
- ~CReferenceActiveDataOwner();
-
- // From CActive
- void RunL();
- TInt RunError(TInt aError);
- void DoCancel();
-
-private:
- CReferenceActiveDataOwner()
- void ConstructL();
- void SubscribeToPSFlag();
- void ProcessBackupStateL(TInt aBackupStateValue);
-
- // Attributes
-private:
- //Active Backup Client
- CActiveBackupClient* iActiveBackupClient;
-
- //The publish and subscribe flag from the Backup Engine
- RProperty iProperty;
-
- //Pointer to the callback implementation
- CReferenceCallbackImplementation* iCallbackImpl;
- };
-
-/** Subscribe to the publish and subscribe flag.
- Call RunL() when the flag changes.
-*/
-void CReferenceActiveDataOwner::SubscribeToPSFlag()
- {
- iStatus = KRequestPending;
- iProperty.Subscribe(iStatus);
- SetActive();
- }
-
-/** Check the flag in case the data owner has been started for a backup or restore,
- or in case the publish and subscribe transition is missed.
-*/
-void CReferenceActiveDataOwner::ConstructL()
- {
- // Set up the property to catch the flag.
- TInt backupStateValue = 0;
- iProperty.Attach(KUidSystemCategory, KUidBackupRestoreKey);
-
- // Process the mode change accordingly
- iProperty.Get(backupStateValue);
- ProcessBackupStateL(backupStateValue);
-
- // Add to the active scheduler
- CActiveScheduler::Add(this);
-
- // Subscribe to the flag to catch transitions
- SubscribeToPSFlag();
-}
-
-/** Create the CActiveBackupClient and the callback implementation
- based on the flag.
-@param aBackupStateValue the new backup state value
-*/
-void CReferenceActiveDataOwner::ProcessBackupStateL(TInt aBackupStateValue)
- {
- TInt type = aBackupStateValue & KBURPartTypeMask;
-
- // Create the the CActiveBackupClient and the callback implementation if
- // the device is in a backup or a restore mode.
- if (type == EBURBackupFull || type == EBURRestoreFull ||
- type == EBURBackupPartial || type == EBURRestorePartial)
- if (iCallbackImpl == NULL)
- {
- iCallbackImpl = CReferenceCallbackImplementation::NewL();
- }
- if (iActiveBackupClient == NULL)
- {
- iActiveBackupClient =
- CActiveBackupClient::NewL(iCallbackImpl);
- }
- }
-
- // Confirm the readiness of the active backup client.
- if ((type == EBURBackupFull || type == EBURRestoreFull) ||
- ((type == EBURBackupPartial || type == EBURRestorePartial) &&
- iActiveBackupClient->DoesPartialBURAffectMeL()))
- {
-
- .... // Things handled by a device vendor.
-
- //Inform the Backup Engine that the client is ready for data supply.
- iActiveBackupClient->ConfirmReadyForBURL(KErrNone);
- }
- else
- {
- // CActiveBackupClient and the callback implementation
- // if it is not an active backup.
- if (iActiveBackupClient != NULL)
- {
- delete iActiveBackupClient;
- iActiveBackupClient = NULL;
- }
-
- // The callback implementation must be deleted after
- // the CActiveBackupClient is deleted.
- if (iCallbackImpl != NULL)
- {
- delete iCallbackImpl;
- iCallbackImpl = NULL;
- }
- }
- }
-
-/** When the flag changes, RunL() is called.
-*/
-void CReferenceActiveDataOwner::RunL()
- {
-
- TInt backupStateValue = 0; // re-set the flag value
-
- // re-subscribe to the flag to monitor future changes
- SubscribeToPSFlag();
-
- iProperty.Get(backupStateValue);
-
- // Process the mode change accordingly
- ProcessBackupStateL(backupStateValue);
- }
-
-...
-</codeblock> </stepxmp>
-</step>
-<step id="GUID-E17042E5-A5FE-56DF-A36C-594B4B5451B2"><cmd/>
-<info>Implement <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> to write
-a callback handler. </info>
-<info>The callback handler prepares the data to the Backup Engine for a backup
-or a restore. For more information about each function, refer to the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> API
-reference. The callback implementation must fulfill the following requirements: </info>
-<substeps id="GUID-90CAC68A-4EDF-5B09-865B-DDDA5128780A">
-<substep id="GUID-30B4E7CC-C5E2-5E37-B8B8-C110953D88FF"><cmd/>
-<info>The Initialise function is usually called before the actual backup or
-restore function is called. For example, <codeph>InitialiseGetBackupDataL()</codeph> is
-called before <codeph>GetBackupDataSectionL()</codeph>. The Initialise function
-gives a chance to a device vendor to prepare the data before the actual data
-supply. </info>
-</substep>
-<substep id="GUID-661B4417-F1E4-5000-AA64-13BAFDB43234"><cmd/>
-<info>In an incremental backup or restore, a snapshot is the dataset after
-each incremental backup or restore. If <codeph>MActiveBackupDataClient::AllSnapshotsSuppliedL()</codeph> is
-called, it means that all snapshots have been supplied to the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref>.
-If <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref> does not receive a snapshot,
-it performs a base backup. </info>
-</substep>
-<substep id="GUID-03A009F5-7E05-5FBE-867A-13F8B93E66E5"><cmd/>
-<info>For a backup function, a <xref href="GUID-4B942C06-1BAC-3A21-B3B1-89FB5C51ADA0.dita"><apiname>TBool</apiname></xref> reference parameter
-named <codeph>aFinished</codeph> is passed as an argument. This indicates
-to the Backup Engine if all of the data for a backup is supplied. Setting
-this to <xref href="GUID-A759CA2D-8327-348F-9337-4886E619D920.dita"><apiname>EFalse</apiname></xref> causes the Backup Engine to repeatedly call
-the backup function for more data. </info>
-</substep>
-<substep id="GUID-174C6057-A621-542E-A1C2-0F3879B4291D"><cmd/>
-<info>For a restore function, <codeph>aFinished</codeph> is passed from the
-Backup Engine to indicate to the data owner if all of the restore data is
-supplied. The Backup Engine sets <codeph>aFinished</codeph> to <xref href="GUID-781E8158-805B-3784-8FED-D7A191822FC3.dita"><apiname>ETrue</apiname></xref> after
-the final call of the restore function. </info>
-</substep>
-<substep id="GUID-26C220A3-2B91-575F-BA73-C19AD7A836E0"><cmd/>
-<info>Any leaves in the callback are propagated over Inter-Processor Communications
-(IPC) to the Backup Engine and potentially to the PC as errors. For this reason,
-any internal calls must be trapped in the callback. </info>
-</substep>
-</substeps>
-<stepxmp><codeblock id="GUID-E20C5B20-8956-50AB-98A8-3FAF1B98B925" xml:space="preserve">class CReferenceCallbackImplementation :
- public CBase,
- public MActiveBackupDataClient
- {
- // Methods
-public:
- static CReferenceCallbackImplementation* NewL();
- ~CReferenceCallbackImplementation();
-
- // The following functions are from the MActiveBackupDataClient
- void AllSnapshotsSuppliedL();
- void ReceiveSnapshotDataL(TDriveNumber aDrive, TDesC8& aBuffer,
- TBool aLastSection);
- TUint GetExpectedDataSize(TDriveNumber aDrive);
- void GetSnapshotDataL(TDriveNumber aDrive, TPtr8& aBuffer,
- TBool& aFinished);
- void InitialiseGetBackupDataL(TDriveNumber aDrive);
- void GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished);
- void InitialiseRestoreBaseDataL(TDriveNumber aDrive);
- void RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished);
- void InitialiseRestoreIncrementDataL(TDriveNumber aDrive);
- void RestoreIncrementDataSectionL(TDesC8& aBuffer, TBool aFinished);
- void RestoreComplete(TDriveNumber aDrive);
- void TerminateMultiStageOperation();
- TUint GetDataChecksum(TDriveNumber aDrive);
-
- //The following two functions are for the proxy backup client only and
- // Symbian provides a default implementation for each function.
- void InitialiseGetProxyBackupDataL(TSecureId aSID, TDriveNumber aDrive);
- void InitialiseRestoreProxyBaseDataL(TSecureId aSID, TDriveNumber aDrive);
-
-private:
- CReferenceCallbackImplementation() {}
- CMyABData* iSnapshot;
- CMyABData* iData;
- TBool iProxy;
- TInt iOffset;
- TInt iSourceSize;
- TUint iFillChar;
- TSecureId iID;
- };
-
-void CReferenceCallbackImplementation::AllSnapshotsSuppliedL()
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::AllSnapshotsSuppliedL()",
- iID.iId);
- }
-
-void CReferenceCallbackImplementation::ReceiveSnapshotDataL(
- TDriveNumber aDrive,
- TDesC8& aBuffer,
- TBool /*aLastSection*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::ReceiveSnapshotDataL()", iID.iId);
- // Create or append a buffer containing the snapshot
- if (!iSnapshot)
- {
- iSnapshot = CMyABData::NewL(aDrive);
- }
-
- iSnapshot->AddDataL(aBuffer);
- }
-
-TUint CReferenceCallbackImplementation::GetExpectedDataSize(TDriveNumber /*aDrive*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetExpectedDataSize()", iID.iId);
-
- return iSourceSize;
- }
-
-void CReferenceCallbackImplementation::GetSnapshotDataL(
- TDriveNumber /*aDrive*/,
- TPtr8& aBuffer,
- TBool& aFinished)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetSnapshotDataL()", iID.iId);
- aBuffer.Append(KABTestSnapshot());
-
- aFinished = ETrue;
- }
-
-void CReferenceCallbackImplementation::InitialiseGetBackupDataL(TDriveNumber /*aDrive*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseGetBackupData()", iID.iId);
- iOffset = 0;
-
- if (!iSnapshot)
- {
- iFillChar = 66;
- }
- else
- {
- iFillChar = 73;
- }
- }
-
-void CReferenceCallbackImplementation::GetBackupDataSectionL(
- TPtr8& aBuffer,
- TBool& aFinished)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetBackupDataSectionL()", iID.iId);
-
- FillBuffer(aBuffer, aFinished);
- }
-
-void CReferenceCallbackImplementation::InitialiseRestoreBaseDataL(TDriveNumber aDrive)
- {
- __LOG("CReferenceCallbackImplementation::InitialiseRestoreBaseDataL()");
-
- iData = CMyABData::NewL(aDrive);
- }
-
-void CReferenceCallbackImplementation::RestoreBaseDataSectionL(
- TDesC8& aBuffer,
- TBool aFinished)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreBaseDataSectionL()", iID.iId);
-
- // append a buffer containing the base data
- iData->AddDataL(aBuffer);
-
- if (aFinished)
- {
- ValidateRestoredData();
-
- delete iData;
- iData = NULL;
- }
- }
-
-void CReferenceCallbackImplementation::InitialiseRestoreIncrementDataL(TDriveNumber aDrive)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseRestoreIncrementDataL()", iID.iId);
- if (!iSnapshot)
- {
- User::Leave(KErrCorrupt);
- }
-
- if (!iData)
- {
- iData = CMyABData::NewL(aDrive);
- }
- }
-
-void CReferenceCallbackImplementation::RestoreIncrementDataSectionL(
- TDesC8& aBuffer,
- TBool aFinished)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreIncrementDataSectionL()", iID.iId);
-
- iData->AddDataL(aBuffer);
-
- if (aFinished)
- {
- ValidateRestoredData();
-
- delete iData;
- iData = NULL;
- }
- }
-
-void CReferenceCallbackImplementation::RestoreComplete(TDriveNumber /*aDrive*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreComplete()", iID.iId);
- }
-
-void CReferenceCallbackImplementation::TerminateMultiStageOperation()
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::TerminateMultiStageOperation()", iID.iId);
- // We also don't do anything here until we start testing multipart?
- }
-
-TUint CReferenceCallbackImplementation::GetDataChecksum(TDriveNumber /*aDrive*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetDataChecksum()", iID.iId);
- return 0;
- }
-
-void CReferenceCallbackImplementation::InitialiseGetProxyBackupDataL(
- TSecureId aSID,
- TDriveNumber /*aDrive*/)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseGetProxyBackupDataL()", iID.iId);
- __LOG2("[0x%08x]: Proxy data about to be requested for SID 0x%08x", iID.iId, aSID.iId);
- iProxy = ETrue;
- iOffset = 0;
-
- iFillChar = 80; // 'P'
- }
-
-void CReferenceCallbackImplementation::InitialiseRestoreProxyBaseDataL(
- TSecureId aSID,
- TDriveNumber aDrive)
- {
- __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseRestoreProxyBaseDataL()", iID.iId);
- __LOG2("[0x%08x]: Proxy data about to be restored for SID 0x%08x", iID.iId, aSID.iId);
- iProxy = ETrue;
- iData = CMyABData::NewL(aDrive);
- }
-...</codeblock> </stepxmp>
-</step>
-<step id="GUID-FBC19F0B-1763-595C-BF4E-F6289AD6EFCA"><cmd/>
-<info>Create a backup registration file to set attribute values for the data
-owner application. </info>
-<info>The Backup Engine parses backup registration files to get the data own
-list. The list includes details of data owners and data for backup and restore. </info>
-<info>Create the file using a text editor and save it as <filepath>backup_registration.xml</filepath> under
-the private folder of the data owner application on the Symbian device. Refer
-to <xref href="GUID-9A6273D8-7797-5190-AFEC-1AD113980B84.dita">Backup Registration
-Files</xref> for more information. </info>
-<substeps id="GUID-08064C91-CC63-502F-807C-D1932C0D05DB">
-<substep id="GUID-D2C54ED8-54C5-564A-B5DF-66CC60F85630"><cmd/>
-<info> <codeph> process_name</codeph> is the name of the data owner application. </info>
-</substep>
-<substep id="GUID-20E42C15-0B8C-5302-8927-1ADB9231AC33"><cmd/>
-<info> <codeph>active_type is set</codeph> to <codeph>activeonly</codeph> for
-an active backup. </info>
-</substep>
-<substep id="GUID-595FE2CF-06C4-599F-9E70-B9B9CD6A71B5"><cmd/>
-<info> <codeph>supports_incremental</codeph> can be set to <codeph>false</codeph> to
-disable the incremental backup support from the active backup client. </info>
-</substep>
-</substeps>
-<stepxmp><codeblock id="GUID-0A5E0FBC-16FD-568A-8530-368101B28EBF" xml:space="preserve"><!-- backup_registration.xml file for referencetestdataowner.exe -->
-
-<?xml version="1.0" standalone="yes"?>
-
-<backup_registration version="1.0">
- <active_backup process_name = "referencetestdataowner.exe"
- active_type = "activeonly"
- requires_delay_to_prepare_data = "yes" <!--deprecated-->
- supports_incremental = "yes">
- </active_backup>
-
- <restore requires_reboot = "no"/> <!--Currently only support no-->
-</backup_registration>
-</codeblock><p>Finally, test the data owner application. The logging information
-appends to the <filepath>securebackup.txt</filepath> log file. To enable the
-log generation, the <filepath>C:\logs\connect</filepath> directory must be
-created on the device. </p> </stepxmp>
-</step>
-</steps>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License
+"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:
+-->
+<!DOCTYPE task
+ PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
+<task id="GUID-DFF9DFC5-1BE0-5CA2-A2B9-27FA2DECFF59" xml:lang="en"><title>Writing
+an Active Backup Client Tutorial</title><shortdesc>A backup client application is often referred to as a data owner
+as it owns the data. This section describes how to write an active backup
+client which works with the Backup Engine and the Backup Server for data backup
+and restore. </shortdesc><prolog><metadata><keywords/></metadata></prolog><taskbody>
+<prereq id="GUID-B83C3258-BE3B-597F-A8EB-5598F059E2E3"><p>Before you start,
+you must understand: </p> <ul>
+<li id="GUID-909ACEA0-363B-585F-AAC7-D85706158930"><p><xref href="GUID-7FDD9FEC-5017-5E5D-A50A-5F343A3C7F6C.dita">Backup
+Engine Concepts</xref> introduce the backup and restore types. </p> </li>
+<li id="GUID-DB7C6BE8-A9A5-592F-BFD2-131FA7139BE2"><p><xref href="GUID-5CA933B9-7987-5DDE-AE12-B0D5AFD31451.dita">Symbian
+Backup and Restore architecture</xref> describes the two ways of data backup
+and restore. </p> </li>
+<li id="GUID-E1A1DC99-39BC-59AD-A2A9-0261D6E689EB"><p><xref href="GUID-937C3D70-2DCC-5084-AC87-3B1E5865A827.dita">Active
+Backup Client Architecture</xref> describes the components involved to do
+active data backup and restore. </p> </li>
+<li id="GUID-1FA3D484-3460-5A81-BD1E-52810746ECD8"><p><xref href="GUID-A81C65CF-CF4E-571C-8080-9D387F46AAD6.dita">Symbian
+Publish and Subscribe</xref> describes how to publish and subscribe events
+using properties. </p> </li>
+</ul> </prereq>
+<context id="GUID-06AB41B7-201A-5EB9-AFF2-1CF231B06118"><p>In an active backup
+and restore, the Backup Engine calls the active backup client to supply the
+data for the backup. Writing an active backup client means to: </p> <ul>
+<li id="GUID-FAAB2D8E-14AD-5866-9D13-26D1DD39EBBC"><p>Create a user defined
+class that has a data member pointer to <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref>. </p> </li>
+<li id="GUID-BB8DB868-66D9-5CE4-8CBD-0D9201365522"><p>Implement the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> interface. </p> </li>
+</ul> </context>
+<steps id="GUID-7D9E4BEE-5BBB-55B1-AB2C-C47E176B0CE7">
+<step id="GUID-95BE7D7F-D355-5CC9-9A02-3351FBC8E709"><cmd/>
+<info>Write an active backup client (data owner) class which must subscribe
+for the <codeph>KUidBackupRestoreKey</codeph> property published by the backup
+server. </info>
+<info>When a backup server receives a request from a client (a host PC) for
+a backup or a restore, it reads backup registration files for a list of data
+owners (refer to step 3). It then calls the <codeph>CSBEClient::SetBURModeL()</codeph> function
+with the registered types (base or incremental, full or partial). This function
+signals start or completion of a backup or restore to all data owners. Data
+owners must subscribe the following publish and subscribe property: </info>
+<substeps id="GUID-29550A41-94C4-5F36-9175-B0FDF2E55483">
+<substep id="GUID-E291A40F-9573-52D7-833D-DDCA3F194B59"><cmd/>
+<info>Key–<codeph>KUidBackupRestoreKey</codeph> defined in the <filepath>epoc32\include\connect\sbdefs.h</filepath> header
+file. This key belongs to the <codeph>KUidSystemCategoryValue</codeph> category. </info>
+</substep>
+<substep id="GUID-774E7565-EB05-5302-B7C7-BD25F6CAFAE0"><cmd/>
+<info>Value–<codeph>TBURPartType</codeph> or <codeph>TBackupIncType</codeph>. </info>
+</substep>
+</substeps>
+<info>The backup client must check the value of the property (flag) on startup,
+in case the device is already in a backup or restore mode. A <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref> object
+can only be created once the publish and subscribe flag has transitioned into
+a backup or restore mode. The backup client can be deleted once the backup
+or restore operation has finished. This releases valuable system resources. </info>
+<info> <codeph>CActiveBackupClient::ConfirmReadyForBURL()</codeph> is called
+to indicate that the backup client is ready for the data supply to the Backup
+Engine. </info>
+<stepxmp><codeblock id="GUID-179BD485-939F-5D89-A123-55FDB8815140" xml:space="preserve">class CReferenceActiveDataOwner : public CActive
+ {
+ // Methods
+public:
+ static CReferenceActiveDataOwner* NewL();
+ ~CReferenceActiveDataOwner();
+
+ // From CActive
+ void RunL();
+ TInt RunError(TInt aError);
+ void DoCancel();
+
+private:
+ CReferenceActiveDataOwner()
+ void ConstructL();
+ void SubscribeToPSFlag();
+ void ProcessBackupStateL(TInt aBackupStateValue);
+
+ // Attributes
+private:
+ //Active Backup Client
+ CActiveBackupClient* iActiveBackupClient;
+
+ //The publish and subscribe flag from the Backup Engine
+ RProperty iProperty;
+
+ //Pointer to the callback implementation
+ CReferenceCallbackImplementation* iCallbackImpl;
+ };
+
+/** Subscribe to the publish and subscribe flag.
+ Call RunL() when the flag changes.
+*/
+void CReferenceActiveDataOwner::SubscribeToPSFlag()
+ {
+ iStatus = KRequestPending;
+ iProperty.Subscribe(iStatus);
+ SetActive();
+ }
+
+/** Check the flag in case the data owner has been started for a backup or restore,
+ or in case the publish and subscribe transition is missed.
+*/
+void CReferenceActiveDataOwner::ConstructL()
+ {
+ // Set up the property to catch the flag.
+ TInt backupStateValue = 0;
+ iProperty.Attach(KUidSystemCategory, KUidBackupRestoreKey);
+
+ // Process the mode change accordingly
+ iProperty.Get(backupStateValue);
+ ProcessBackupStateL(backupStateValue);
+
+ // Add to the active scheduler
+ CActiveScheduler::Add(this);
+
+ // Subscribe to the flag to catch transitions
+ SubscribeToPSFlag();
+}
+
+/** Create the CActiveBackupClient and the callback implementation
+ based on the flag.
+@param aBackupStateValue the new backup state value
+*/
+void CReferenceActiveDataOwner::ProcessBackupStateL(TInt aBackupStateValue)
+ {
+ TInt type = aBackupStateValue & KBURPartTypeMask;
+
+ // Create the the CActiveBackupClient and the callback implementation if
+ // the device is in a backup or a restore mode.
+ if (type == EBURBackupFull || type == EBURRestoreFull ||
+ type == EBURBackupPartial || type == EBURRestorePartial)
+ if (iCallbackImpl == NULL)
+ {
+ iCallbackImpl = CReferenceCallbackImplementation::NewL();
+ }
+ if (iActiveBackupClient == NULL)
+ {
+ iActiveBackupClient =
+ CActiveBackupClient::NewL(iCallbackImpl);
+ }
+ }
+
+ // Confirm the readiness of the active backup client.
+ if ((type == EBURBackupFull || type == EBURRestoreFull) ||
+ ((type == EBURBackupPartial || type == EBURRestorePartial) &&
+ iActiveBackupClient->DoesPartialBURAffectMeL()))
+ {
+
+ .... // Things handled by a device vendor.
+
+ //Inform the Backup Engine that the client is ready for data supply.
+ iActiveBackupClient->ConfirmReadyForBURL(KErrNone);
+ }
+ else
+ {
+ // CActiveBackupClient and the callback implementation
+ // if it is not an active backup.
+ if (iActiveBackupClient != NULL)
+ {
+ delete iActiveBackupClient;
+ iActiveBackupClient = NULL;
+ }
+
+ // The callback implementation must be deleted after
+ // the CActiveBackupClient is deleted.
+ if (iCallbackImpl != NULL)
+ {
+ delete iCallbackImpl;
+ iCallbackImpl = NULL;
+ }
+ }
+ }
+
+/** When the flag changes, RunL() is called.
+*/
+void CReferenceActiveDataOwner::RunL()
+ {
+
+ TInt backupStateValue = 0; // re-set the flag value
+
+ // re-subscribe to the flag to monitor future changes
+ SubscribeToPSFlag();
+
+ iProperty.Get(backupStateValue);
+
+ // Process the mode change accordingly
+ ProcessBackupStateL(backupStateValue);
+ }
+
+...
+</codeblock> </stepxmp>
+</step>
+<step id="GUID-E17042E5-A5FE-56DF-A36C-594B4B5451B2"><cmd/>
+<info>Implement <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> to write
+a callback handler. </info>
+<info>The callback handler prepares the data to the Backup Engine for a backup
+or a restore. For more information about each function, refer to the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-DB245BC3-2ADA-311D-8024-B40335D22822"><apiname>conn::MActiveBackupDataClient</apiname></xref> API
+reference. The callback implementation must fulfill the following requirements: </info>
+<substeps id="GUID-90CAC68A-4EDF-5B09-865B-DDDA5128780A">
+<substep id="GUID-30B4E7CC-C5E2-5E37-B8B8-C110953D88FF"><cmd/>
+<info>The Initialise function is usually called before the actual backup or
+restore function is called. For example, <codeph>InitialiseGetBackupDataL()</codeph> is
+called before <codeph>GetBackupDataSectionL()</codeph>. The Initialise function
+gives a chance to a device vendor to prepare the data before the actual data
+supply. </info>
+</substep>
+<substep id="GUID-661B4417-F1E4-5000-AA64-13BAFDB43234"><cmd/>
+<info>In an incremental backup or restore, a snapshot is the dataset after
+each incremental backup or restore. If <codeph>MActiveBackupDataClient::AllSnapshotsSuppliedL()</codeph> is
+called, it means that all snapshots have been supplied to the <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref>.
+If <xref href="GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2.dita#GUID-169BB4E2-5B0E-3719-A7B8-A3C0AAA602E2/GUID-17E48B80-2421-3256-B8B4-A0FED424D54A"><apiname>conn::CActiveBackupClient</apiname></xref> does not receive a snapshot,
+it performs a base backup. </info>
+</substep>
+<substep id="GUID-03A009F5-7E05-5FBE-867A-13F8B93E66E5"><cmd/>
+<info>For a backup function, a <xref href="GUID-4B942C06-1BAC-3A21-B3B1-89FB5C51ADA0.dita"><apiname>TBool</apiname></xref> reference parameter
+named <codeph>aFinished</codeph> is passed as an argument. This indicates
+to the Backup Engine if all of the data for a backup is supplied. Setting
+this to <xref href="GUID-A759CA2D-8327-348F-9337-4886E619D920.dita"><apiname>EFalse</apiname></xref> causes the Backup Engine to repeatedly call
+the backup function for more data. </info>
+</substep>
+<substep id="GUID-174C6057-A621-542E-A1C2-0F3879B4291D"><cmd/>
+<info>For a restore function, <codeph>aFinished</codeph> is passed from the
+Backup Engine to indicate to the data owner if all of the restore data is
+supplied. The Backup Engine sets <codeph>aFinished</codeph> to <xref href="GUID-781E8158-805B-3784-8FED-D7A191822FC3.dita"><apiname>ETrue</apiname></xref> after
+the final call of the restore function. </info>
+</substep>
+<substep id="GUID-26C220A3-2B91-575F-BA73-C19AD7A836E0"><cmd/>
+<info>Any leaves in the callback are propagated over Inter-Processor Communications
+(IPC) to the Backup Engine and potentially to the PC as errors. For this reason,
+any internal calls must be trapped in the callback. </info>
+</substep>
+</substeps>
+<stepxmp><codeblock id="GUID-E20C5B20-8956-50AB-98A8-3FAF1B98B925" xml:space="preserve">class CReferenceCallbackImplementation :
+ public CBase,
+ public MActiveBackupDataClient
+ {
+ // Methods
+public:
+ static CReferenceCallbackImplementation* NewL();
+ ~CReferenceCallbackImplementation();
+
+ // The following functions are from the MActiveBackupDataClient
+ void AllSnapshotsSuppliedL();
+ void ReceiveSnapshotDataL(TDriveNumber aDrive, TDesC8& aBuffer,
+ TBool aLastSection);
+ TUint GetExpectedDataSize(TDriveNumber aDrive);
+ void GetSnapshotDataL(TDriveNumber aDrive, TPtr8& aBuffer,
+ TBool& aFinished);
+ void InitialiseGetBackupDataL(TDriveNumber aDrive);
+ void GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished);
+ void InitialiseRestoreBaseDataL(TDriveNumber aDrive);
+ void RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished);
+ void InitialiseRestoreIncrementDataL(TDriveNumber aDrive);
+ void RestoreIncrementDataSectionL(TDesC8& aBuffer, TBool aFinished);
+ void RestoreComplete(TDriveNumber aDrive);
+ void TerminateMultiStageOperation();
+ TUint GetDataChecksum(TDriveNumber aDrive);
+
+ //The following two functions are for the proxy backup client only and
+ // Symbian provides a default implementation for each function.
+ void InitialiseGetProxyBackupDataL(TSecureId aSID, TDriveNumber aDrive);
+ void InitialiseRestoreProxyBaseDataL(TSecureId aSID, TDriveNumber aDrive);
+
+private:
+ CReferenceCallbackImplementation() {}
+ CMyABData* iSnapshot;
+ CMyABData* iData;
+ TBool iProxy;
+ TInt iOffset;
+ TInt iSourceSize;
+ TUint iFillChar;
+ TSecureId iID;
+ };
+
+void CReferenceCallbackImplementation::AllSnapshotsSuppliedL()
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::AllSnapshotsSuppliedL()",
+ iID.iId);
+ }
+
+void CReferenceCallbackImplementation::ReceiveSnapshotDataL(
+ TDriveNumber aDrive,
+ TDesC8& aBuffer,
+ TBool /*aLastSection*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::ReceiveSnapshotDataL()", iID.iId);
+ // Create or append a buffer containing the snapshot
+ if (!iSnapshot)
+ {
+ iSnapshot = CMyABData::NewL(aDrive);
+ }
+
+ iSnapshot->AddDataL(aBuffer);
+ }
+
+TUint CReferenceCallbackImplementation::GetExpectedDataSize(TDriveNumber /*aDrive*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetExpectedDataSize()", iID.iId);
+
+ return iSourceSize;
+ }
+
+void CReferenceCallbackImplementation::GetSnapshotDataL(
+ TDriveNumber /*aDrive*/,
+ TPtr8& aBuffer,
+ TBool& aFinished)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetSnapshotDataL()", iID.iId);
+ aBuffer.Append(KABTestSnapshot());
+
+ aFinished = ETrue;
+ }
+
+void CReferenceCallbackImplementation::InitialiseGetBackupDataL(TDriveNumber /*aDrive*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseGetBackupData()", iID.iId);
+ iOffset = 0;
+
+ if (!iSnapshot)
+ {
+ iFillChar = 66;
+ }
+ else
+ {
+ iFillChar = 73;
+ }
+ }
+
+void CReferenceCallbackImplementation::GetBackupDataSectionL(
+ TPtr8& aBuffer,
+ TBool& aFinished)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetBackupDataSectionL()", iID.iId);
+
+ FillBuffer(aBuffer, aFinished);
+ }
+
+void CReferenceCallbackImplementation::InitialiseRestoreBaseDataL(TDriveNumber aDrive)
+ {
+ __LOG("CReferenceCallbackImplementation::InitialiseRestoreBaseDataL()");
+
+ iData = CMyABData::NewL(aDrive);
+ }
+
+void CReferenceCallbackImplementation::RestoreBaseDataSectionL(
+ TDesC8& aBuffer,
+ TBool aFinished)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreBaseDataSectionL()", iID.iId);
+
+ // append a buffer containing the base data
+ iData->AddDataL(aBuffer);
+
+ if (aFinished)
+ {
+ ValidateRestoredData();
+
+ delete iData;
+ iData = NULL;
+ }
+ }
+
+void CReferenceCallbackImplementation::InitialiseRestoreIncrementDataL(TDriveNumber aDrive)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseRestoreIncrementDataL()", iID.iId);
+ if (!iSnapshot)
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ if (!iData)
+ {
+ iData = CMyABData::NewL(aDrive);
+ }
+ }
+
+void CReferenceCallbackImplementation::RestoreIncrementDataSectionL(
+ TDesC8& aBuffer,
+ TBool aFinished)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreIncrementDataSectionL()", iID.iId);
+
+ iData->AddDataL(aBuffer);
+
+ if (aFinished)
+ {
+ ValidateRestoredData();
+
+ delete iData;
+ iData = NULL;
+ }
+ }
+
+void CReferenceCallbackImplementation::RestoreComplete(TDriveNumber /*aDrive*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::RestoreComplete()", iID.iId);
+ }
+
+void CReferenceCallbackImplementation::TerminateMultiStageOperation()
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::TerminateMultiStageOperation()", iID.iId);
+ // We also don't do anything here until we start testing multipart?
+ }
+
+TUint CReferenceCallbackImplementation::GetDataChecksum(TDriveNumber /*aDrive*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::GetDataChecksum()", iID.iId);
+ return 0;
+ }
+
+void CReferenceCallbackImplementation::InitialiseGetProxyBackupDataL(
+ TSecureId aSID,
+ TDriveNumber /*aDrive*/)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseGetProxyBackupDataL()", iID.iId);
+ __LOG2("[0x%08x]: Proxy data about to be requested for SID 0x%08x", iID.iId, aSID.iId);
+ iProxy = ETrue;
+ iOffset = 0;
+
+ iFillChar = 80; // 'P'
+ }
+
+void CReferenceCallbackImplementation::InitialiseRestoreProxyBaseDataL(
+ TSecureId aSID,
+ TDriveNumber aDrive)
+ {
+ __LOG1("[0x%08x]: CReferenceCallbackImplementation::InitialiseRestoreProxyBaseDataL()", iID.iId);
+ __LOG2("[0x%08x]: Proxy data about to be restored for SID 0x%08x", iID.iId, aSID.iId);
+ iProxy = ETrue;
+ iData = CMyABData::NewL(aDrive);
+ }
+...</codeblock> </stepxmp>
+</step>
+<step id="GUID-FBC19F0B-1763-595C-BF4E-F6289AD6EFCA"><cmd/>
+<info>Create a backup registration file to set attribute values for the data
+owner application. </info>
+<info>The Backup Engine parses backup registration files to get the data own
+list. The list includes details of data owners and data for backup and restore. </info>
+<info>Create the file using a text editor and save it as <filepath>backup_registration.xml</filepath> under
+the private folder of the data owner application on the Symbian device. Refer
+to <xref href="GUID-9A6273D8-7797-5190-AFEC-1AD113980B84.dita">Backup Registration
+Files</xref> for more information. </info>
+<substeps id="GUID-08064C91-CC63-502F-807C-D1932C0D05DB">
+<substep id="GUID-D2C54ED8-54C5-564A-B5DF-66CC60F85630"><cmd/>
+<info> <codeph> process_name</codeph> is the name of the data owner application. </info>
+</substep>
+<substep id="GUID-20E42C15-0B8C-5302-8927-1ADB9231AC33"><cmd/>
+<info> <codeph>active_type is set</codeph> to <codeph>activeonly</codeph> for
+an active backup. </info>
+</substep>
+<substep id="GUID-595FE2CF-06C4-599F-9E70-B9B9CD6A71B5"><cmd/>
+<info> <codeph>supports_incremental</codeph> can be set to <codeph>false</codeph> to
+disable the incremental backup support from the active backup client. </info>
+</substep>
+</substeps>
+<stepxmp><codeblock id="GUID-0A5E0FBC-16FD-568A-8530-368101B28EBF" xml:space="preserve"><!-- backup_registration.xml file for referencetestdataowner.exe -->
+
+<?xml version="1.0" standalone="yes"?>
+
+<backup_registration version="1.0">
+ <active_backup process_name = "referencetestdataowner.exe"
+ active_type = "activeonly"
+ requires_delay_to_prepare_data = "yes" <!--deprecated-->
+ supports_incremental = "yes">
+ </active_backup>
+
+ <restore requires_reboot = "no"/> <!--Currently only support no-->
+</backup_registration>
+</codeblock><p>Finally, test the data owner application. The logging information
+appends to the <filepath>securebackup.txt</filepath> log file. To enable the
+log generation, the <filepath>C:\logs\connect</filepath> directory must be
+created on the device. </p> </stepxmp>
+</step>
+</steps>
</taskbody></task>
\ No newline at end of file