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