1# Backup and Restore Triggered by System Applications
2
3The backup and restore framework provides a solution for backing up and restoring data of applications and services on a device. You can follow the procedure below to enable an application to trigger data backup or restoration:
4
5- [Obtain capability files](#obtaining-capability-files): Obtain capability files of all applications of the user in the system. The capability files are indispensable for data backup and restoration.
6
7- [Back up application data](#backing-up-application-data): Back up the application data based on the application information in the capability files.
8
9- [Restore application data](#restoring-application-data): Restore the application data based on the application information in the capability files.
10
11## How to Develop
12
13For details about how to use the APIs, see [Backup and Restore](../reference/apis-core-file-kit/js-apis-file-backup-sys.md).
14
15Before using the APIs, you need to:
16
171. Apply for the ohos.permission.BACKUP permission. For details, see [Requesting Permissions for system_basic Applications](../security/AccessToken/determine-application-mode.md#requesting-permissions-for-system_basic-applications).
18
192. Import **@ohos.file.backup**.
20
21   ```js
22   import backup from '@ohos.file.backup';
23   ```
24
25## Obtaining Capability Files
26
27Obtain capability files of all applications of the current user. The capability files are indispensable for application data backup and restoration.
28
29The capability file of an application contains the device type, device version, and basic application information, such as the application name, application size, application version, whether to allow backup and restoration, and whether to install the application during restoration.
30
31Call [backup.getLocalCapabilities()](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#backupgetlocalcapabilities) to obtain the capability file.
32
33```ts
34import backup from '@ohos.file.backup';
35import common from '@ohos.app.ability.common';
36import fs from '@ohos.file.fs';
37import { BusinessError } from '@ohos.base';
38
39// Obtain the application file path.
40let context = getContext(this) as common.UIAbilityContext;
41let filesDir = context.filesDir;
42
43async function getLocalCapabilities(): Promise<void> {
44 try {
45   let fileData = await backup.getLocalCapabilities();
46   console.info('getLocalCapabilities success');
47   let fpath = filesDir + '/localCapabilities.json';
48   fs.copyFileSync(fileData.fd, fpath);
49   fs.closeSync(fileData.fd);
50 } catch (error) {
51   let err: BusinessError = error as BusinessError;
52   console.error('getLocalCapabilities failed with err: ' + JSON.stringify(err));
53 }
54}
55```
56
57**Capability file example**
58
59| Name      | Type| Mandatory| Description                  |
60| -------------- | -------- | ---- | ---------------------- |
61| bundleInfos    | Array    | Yes  | Application information.          |
62| allToBackup    | Boolean  | Yes  | Whether to allow backup and restoration.      |
63| extensionName  | String  | Yes  | Extension name of the application.          |
64| name           | String  | Yes  | Bundle name of the application.            |
65| needToInstall  | Boolean  | Yes  | Whether to install the application during data restoration.|
66| spaceOccupied  | Number    | Yes  | Space occupied by the application data.|
67| versionCode    | Number    | Yes  | Application version number.          |
68| versionName    | String  | Yes  | Application version name.        |
69| deviceType     | String  | Yes  | Type of the device.              |
70| systemFullName | String  | Yes  | Device version.              |
71
72```json
73{
74"bundleInfos" :[{
75 "allToBackup" : true,
76 "extensionName" : "BackupExtensionAbility",
77 "name" : "com.example.hiworld",
78 "needToInstall" : false,
79 "spaceOccupied" : 0,
80 "versionCode" : 1000000,
81 "versionName" : "1.0.0"
82 }],
83"deviceType" : "default",
84"systemFullName" : "OpenHarmony-4.0.0.0"
85}
86```
87
88## Backing Up Application Data
89
90You can select the application data to be backed up based on the application information in the capability files.
91
92The Backup & Restore service packages the application data to be backed up. The package file handle is returned by the [onFileReady](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#onfileready) callback registered when the **SessionBackup** instance is created.
93
94You can save the file to a local directory as required.
95
96**Example**
97
98 ```ts
99  import backup from '@ohos.file.backup';
100  import common from '@ohos.app.ability.common';
101  import fs from '@ohos.file.fs';
102  import { BusinessError } from '@ohos.base';
103
104  // Obtain the sandbox path.
105  let context = getContext(this) as common.UIAbilityContext;
106  let filesDir = context.filesDir;
107  // Create a SessionBackup instance for data backup.
108  let g_session: backup.SessionBackup;
109  function createSessionBackup(): backup.SessionBackup {
110    let generalCallbacks: backup.GeneralCallbacks = {
111      // onFileReady is called to return a data complete notification to the application. Avoid time-consuming implementations in onFileReady. You can use asynchronous threads to process data based on the file FD.
112      onFileReady: (err: BusinessError, file: backup.File) => {
113        if (err) {
114          console.info('onFileReady err: ' + JSON.stringify(err));
115        }
116        try {
117          let bundlePath = filesDir + '/' + file.bundleName;
118          if (!fs.accessSync(bundlePath)) {
119            fs.mkdirSync(bundlePath);
120          }
121          // Calling copyFileSync causes one more memory copy. To reduce memory consumption, you can use the FD returned by onFileReady for data processing, and close the FD after data is processed.
122          fs.copyFileSync(file.fd, bundlePath + `/${file.uri}`);
123          fs.closeSync(file.fd);
124          console.info('onFileReady success');
125        } catch (e) {
126          console.error('onFileReady failed with err: ' + e);
127        }
128      },
129      onBundleBegin: (err: BusinessError<string|void>, bundleName: string) => {
130        if (err) {
131          console.info('onBundleBegin err: ' + JSON.stringify(err));
132        } else {
133          console.info('onBundleBegin bundleName: ' + bundleName);
134        }
135      },
136      onBundleEnd: (err: BusinessError<string|void>, bundleName: string) => {
137        if (err) {
138          console.info('onBundleEnd err: ' + JSON.stringify(err));
139        } else {
140          console.info('onBundleEnd bundleName: ' + bundleName);
141        }
142      },
143      onAllBundlesEnd: (err: BusinessError) => {
144        if (err) {
145          console.info('onAllBundlesEnd err: ' + JSON.stringify(err));
146        } else {
147          console.info('onAllBundlesEnd');
148        }
149      },
150      onBackupServiceDied: () => {
151        console.info('onBackupServiceDied');
152      },
153      onResultReport: (bundleName: string, result: string) => {
154        console.info('onResultReport  bundleName: ' + bundleName);
155        console.info('onResultReport  result: ' + result);
156      },
157      onProcess:(bundleName: string, process: string) => {
158        console.info('onPross bundleName: ' + JSON.stringify(bundleName));
159        console.info('onPross result: ' + JSON.stringify(process));
160      }
161    }
162    let sessionBackup = new backup.SessionBackup(generalCallbacks);
163    return sessionBackup;
164  }
165
166  async function sessionBackup (): Promise<void> {
167    g_session = createSessionBackup();
168    // Select the application to be backed up based on the capability file obtained by backup.getLocalCapabilities().
169    // You can also back up data based on the application bundle name.
170    const backupApps: string[] = [
171      "com.example.hiworld",
172    ]
173    await g_session.appendBundles(backupApps);
174    console.info('appendBundles success');
175  }
176 ```
177
178## Restoring Application Data
179
180You can select the application data to be restored based on the application information in the capability files.
181
182The Backup and Restore service returns the FD of the application data to be restored in the [onFileReady](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#onfileready) callback registered when the **SessionRestore** instance is created. The file handle is obtained by [getFileHandle](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#getfilehandle). Then, the data to be restored is written to the file handle based on the [uri](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#filemeta) returned. After the data is written, use [publishFile](../reference/apis-core-file-kit/js-apis-file-backup-sys.md#publishfile) to notify the service that the data write is complete.
183
184When all the data of the application is ready, the service starts to restore the application data.
185
186**Example**
187
188 ```ts
189  import backup from '@ohos.file.backup';
190  import fs from '@ohos.file.fs';
191  import { BusinessError } from '@ohos.base';
192  // Create a SessionRestore instance for data restoration.
193  let g_session: backup.SessionRestore;
194  let initMap = new Map<string, number>();
195  testFileNum = 123; // Number of files initialized.
196  let testBundleName = 'com.example.myapplication'; // Test bundle name.
197  initMap.set(testBundleName, testFileNum);
198  let countMap = new Map<string, number>();
199  countMap.set(testBundleName, 0); // Initialization count.
200  async function publishFile(file: backup.File): Promise<void> {
201    let fileMeta: backup.FileMeta = {
202      bundleName: file.bundleName,
203      uri: ''
204    }
205    await g_session.publishFile(fileMeta);
206  }
207  function createSessionRestore(): backup.SessionRestore {
208    let generalCallbacks: backup.GeneralCallbacks = {
209      onFileReady: (err: BusinessError, file: backup.File) => {
210        if (err) {
211          console.info('onFileReady err: ' + JSON.stringify(err));
212        }
213        // Set bundlePath based on the actual situation.
214        let bundlePath: string = '';
215        if (!fs.accessSync(bundlePath)) {
216          console.info('onFileReady bundlePath err : ' + bundlePath);
217        }
218        fs.copyFileSync(bundlePath, file.fd);
219        fs.closeSync(file.fd);
220        // After the data is transferred, notify the server that the files are ready.
221        countMap[file.bundleName]++;
222        if (countMap[file.bundleName] == initMap[file.bundleName]) { // Trigger publishFile when all the files of each bundle are received.
223          publishFile(file);
224        }
225        console.info('onFileReady success');
226      },
227      onBundleBegin: (err: BusinessError<string|void>, bundleName: string) => {
228        if (err) {
229          console.error('onBundleBegin failed with err: ' + JSON.stringify(err));
230        }
231        console.info('onBundleBegin success');
232      },
233      onBundleEnd: (err: BusinessError<string|void>, bundleName: string) => {
234        if (err) {
235          console.error('onBundleEnd failed with err: ' + JSON.stringify(err));
236        }
237        console.info('onBundleEnd success');
238      },
239      onAllBundlesEnd: (err: BusinessError) => {
240        if (err) {
241          console.error('onAllBundlesEnd failed with err: ' + JSON.stringify(err));
242        }
243        console.info('onAllBundlesEnd success');
244      },
245      onBackupServiceDied: () => {
246        console.info('service died');
247      },
248      onResultReport: (bundleName: string, result: string) => {
249        console.info('onResultReport  bundleName: ' + bundleName);
250        console.info('onResultReport  result: ' + result);
251      },
252      onProcess:(bundleName: string, process: string) => {
253        console.info('onPross bundleName: ' + JSON.stringify(bundleName));
254        console.info('onPross result: ' + JSON.stringify(process));
255      }
256    }
257    let sessionRestore = new backup.SessionRestore(generalCallbacks);
258    return sessionRestore;
259  }
260
261  async function restore01 (): Promise<void> {
262    g_session = createSessionRestore();
263    const restoreApps: string[] = [
264      "com.example.hiworld",
265    ]
266    // You can obtain the capability file based on actual situation. The following is an example only.
267    // You can also construct capability files as required.
268    let fileData = await backup.getLocalCapabilities();
269    await g_session.appendBundles(fileData.fd, restoreApps);
270    console.info('appendBundles success');
271    // After the applications to be restored are added, call getFileHandle() to obtain the handles of the application files to be restored based on the application name.
272    // The number of application data files to be restored varies depending on the number of backup files. The following is only an example.
273    let handle: backup.FileMeta = {
274      bundleName: restoreApps[0],
275      uri: "manage.json"
276    }
277    await g_session.getFileHandle(handle);
278    handle.uri = "1.tar";
279    await g_session.getFileHandle(handle);
280    console.info('getFileHandle success');
281  }
282 ```
283