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