1# Applying for Permissions 2 3## When to Use 4 5Application permissions are used to prevent unauthorized access to sensitive data or critical functions. The [Ability Privilege Level (APL)](accesstoken-overview.md#application-apls) of an application can be normal (default), system_basic, or system_core. The [permission types](accesstoken-overview.md#permission-types) include system_grant and user_grant. For details about the application permissions, see the [Application Permission List](permission-list.md). 6 7This document describes the following operations: 8 9- [Declaring Permissions in the Configuration File](#declaring-permissions-in-the-configuration-file) 10- [Declaring the ACL](#declaring-the-acl) 11- [Requesting User Authorization](#requesting-user-authorization) 12- [Pre-authorizing user_grant Permissions](#pre-authorizing-user_grant-permissions) 13 14## Declaring Permissions in the Configuration File 15 16The permissions required by an application must be declared one by one in the configuration file of the project. Otherwise, the application cannot obtain the permissions. 17 18> **NOTE** 19> 20> If an application of the normal APL requires a permission of the system_basic or system_core level, you must also declare the permission in the [ACL](#declaring-the-acl). 21 22The following table describes the fields in the configuration file. 23 24| Field | Mandatory| Description | 25| --------- | -------- | ------------------------------------------------------------ | 26| name | Yes | Name of the permission. | 27| reason | No | Reason for applying for the permission. For details, see [Specifications for reason](#specifications-for-reason).<br>This parameter is mandatory when a user_grant permission is required.| 28| usedScene | No | Application scenario of the permission.<br>This parameter is mandatory when a user_grant permission is required.| 29| abilities | No | Abilities that require the permission. The value is an array.<br>**Applicable model**: stage| 30| ability | No | Abilities that require the permission. The value is an array.<br>**Applicable model**: FA| 31| when | No | Time when the permission is required. <br>Value:<br>- **inuse**: The permission is required only when the application is in use.<br>- **always**: The permission is required no matter whether the application is in use.| 32 33### Stage Model 34 35If your application is developed based on the stage model, declare the required permissions in [**module.json5**](../quick-start/module-configuration-file.md). 36 37```json 38{ 39 "module" : { 40 // ... 41 "requestPermissions":[ 42 { 43 "name" : "ohos.permission.PERMISSION1", 44 "reason": "$string:reason", 45 "usedScene": { 46 "abilities": [ 47 "FormAbility" 48 ], 49 "when":"inuse" 50 } 51 }, 52 { 53 "name" : "ohos.permission.PERMISSION2", 54 "reason": "$string:reason", 55 "usedScene": { 56 "abilities": [ 57 "FormAbility" 58 ], 59 "when":"always" 60 } 61 } 62 ] 63 } 64} 65``` 66 67### FA Model 68 69If your application is developed based on the FA model, declare the required permissions in **config.json**. 70 71```json 72{ 73 "module" : { 74 // ... 75 "reqPermissions":[ 76 { 77 "name" : "ohos.permission.PERMISSION1", 78 "reason": "$string:reason", 79 "usedScene": { 80 "ability": [ 81 "FormAbility" 82 ], 83 "when":"inuse" 84 } 85 }, 86 { 87 "name" : "ohos.permission.PERMISSION2", 88 "reason": "$string:reason", 89 "usedScene": { 90 "ability": [ 91 "FormAbility" 92 ], 93 "when":"always" 94 } 95 } 96 ] 97 } 98} 99``` 100 101### Specifications for reason 102 103The **reason** field (reason for applying for the permission) is mandatory when a user_grant permission is required. You need to configure each permission required by your application in the application configuration file. 104 105When the user_grant permissions are authorized by the user in a dialog box, the [permission group](accesstoken-overview.md#permission group and sub-permissions) is displayed. For details about the permission groups, see [Application Permission List](permission-group-list.md). 106 107The **reason** field must comply with the following specifications: 108 1091. The reason must be clear and concise without redundant separators. 110 111 **Recommended sentence pattern**: Used for something/Used to do something/Used for doing something. 112 113 **Example**: Used for code scanning and photographing. 114 1152. To ensure optimal user experience, the recommended length of **reason** is fewer than 72 characters (36 Chinese characters displayed in two lines on the UI) and the maximum length is 256 characters. 116 1173. If **reason** is not set, the default reason will be used. 118 119The reason for using a permission is presented in the permission authorization window and **Settings**. The path for **Settings** is **Settings** > **Privacy** > **Permission manager** > Permission details of an app. 120 1211. If permissions in the **Phone**, **Messaging**, **Calendar**, **Contacts**, and **Call logs** permission groups are required, the content and usage of the permissions must be presented to the user. 122 123 **Sentence pattern**: Permissions A and B, used to ... 124 125 **Example**: Permission A and permission B, used to obtain the call status and mobile network information and for secure operation and statistics charging services. 126 1272. If permissions in other permission groups are required, the reason for using the first permission requested in the permission group is presented to the user. The permissions are listed in the same sequence as they are sorted in permission groups of **Permission manager**. 128 129 **Example**: If Permission group A = {permission A, permission B, permission C} and {permission C, permission B} are requested, the reason for using permission B is presented to the user. 130 131## Declaring the ACL 132 133If an application of the normal APL requires permissions of the system_basic or system_core level, you must also declare the required permissions in the ACL. 134 135For example, if an application needs to access audio clips of a user and capture screenshots, it requires the ohos.permission.WRITE_AUDIO permission (of the system_basic level) and the ohos.permission.CAPTURE_SCREEN permission (of the system_core level). In this case, you need to add the required permissions to the **acls** field in the [HarmonyAppProvision configuration file](app-provision-structure.md). 136 137```json 138{ 139 // ... 140 "acls":{ 141 "allowed-acls":[ 142 "ohos.permission.WRITE_AUDIO", 143 "ohos.permission.CAPTURE_SCREEN" 144 ] 145 } 146} 147``` 148 149## Requesting User Authorization 150 151User authorization is required when an application needs to access user privacy information (such as Location or Calendar information) or using system abilities (such as the camera ability to take photos or record videos). In this case, the application requires a user_grant permission. Before the application accesses the data or using the system ability, a verification is performed to check whether the user has granted the permission to the application. If the user has not granted the permission, a dialog box will be displayed to request user authorization. The following figure shows an example. 152 153**Figure 1** Requesting user authorization 154 155 156 157> **NOTE** 158> 159> Each time before an API protected by a user_grant permission is called, **[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)** will be called to request user authorization. After the permission is granted, the user may revoke the authorization in **Settings**. Therefore, the previous authorization status cannot be persistent. 160 161### Stage Model 162 163Example: Apply for the permission for an application to access the Calendar. 164 1651. Declare the **ohos.permission.READ_CALENDAR** permission in the configuration file. For details, see [Declaring Permissions in the Configuration File](#declaring-permissions-in-the-configuration-file). 166 1672. Check whether the user has granted the permission. 168 169 Use [checkAccessToken()](../reference/apis/js-apis-abilityAccessCtrl.md#checkaccesstoken9) to check whether the user has granted the permission. If yes, the application can access the Calendar. Otherwise, user authorization is required. 170 171 ```typescript 172 import bundleManager from '@ohos.bundle.bundleManager'; 173 import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 174 import { BusinessError } from '@ohos.base'; 175 176 async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> { 177 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 178 let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED; 179 180 // Obtain the access token ID of the application. 181 let tokenId: number = 0; 182 try { 183 let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); 184 let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo; 185 tokenId = appInfo.accessTokenId; 186 } catch (error) { 187 let err: BusinessError = error as BusinessError; 188 console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`); 189 } 190 191 // Check whether the user has granted the permission. 192 try { 193 grantStatus = await atManager.checkAccessToken(tokenId, permission); 194 } catch (error) { 195 let err: BusinessError = error as BusinessError; 196 console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`); 197 } 198 199 return grantStatus; 200 } 201 202 async function checkPermissions(): Promise<void> { 203 const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR']; 204 let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]); 205 206 if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 207 // If the user has granted the permission, the application can access the Calendar. 208 } else { 209 // Apply for the permission to access the Calendar. 210 } 211 } 212 ``` 213 2143. Request user authorization dynamically. 215 216 Use [requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) to apply for permissions from the user when the application is running. A list of permissions, such as the permissions to access the Location, Calendar, camera, and microphone, can be passed in. The user can grant or deny the permissions. 217 218 You can have [**requestPermissionsFromUser()**](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) called in **onWindowStageCreate()** of the UIAbility to dynamically request user authorization, or request user authorization on the UI based on service requirements. 219 220 Sample code for requesting user authorization using UIAbility: 221 222 ```typescript 223 import UIAbility from '@ohos.app.ability.UIAbility'; 224 import window from '@ohos.window'; 225 import abilityAccessCtrl, { Context, PermissionRequestResult, Permissions } from '@ohos.abilityAccessCtrl'; 226 import { BusinessError } from '@ohos.base'; 227 228 const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR']; 229 export default class EntryAbility extends UIAbility { 230 // ... 231 onWindowStageCreate(windowStage: window.WindowStage) { 232 // Main window is created. Set the main page for this ability. 233 let context: Context = this.context; 234 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 235 // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. 236 237 atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => { 238 let grantStatus: Array<number> = data.authResults; 239 let length: number = grantStatus.length; 240 for (let i = 0; i < length; i++) { 241 if (grantStatus[i] === 0) { 242 // If the user has granted the permission, the application can access the Calendar. 243 } else { 244 // If the user has not granted the permission, display a message indicating that user authorization is required, and direct the user to the Settings page to set the permission. 245 return; 246 } 247 } 248 // The authorization is successful. 249 }).catch((err: BusinessError) => { 250 console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); 251 }) 252 // ... 253 } 254 } 255 ``` 256 257 Sample code for requesting user authorization on the UI: 258 259 ```typescript 260 import abilityAccessCtrl, { Context, PermissionRequestResult, Permissions } from '@ohos.abilityAccessCtrl'; 261 import { BusinessError } from '@ohos.base'; 262 263 const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR']; 264 265 @Entry 266 @Component 267 struct Index { 268 reqPermissionsFromUser(permissions: Array<Permissions>): void { 269 let context: Context = getContext(this) as common.UIAbilityContext; 270 let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 271 // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. 272 atManager.requestPermissionsFromUser(context, permissions).then((data: PermissionRequestResult) => { 273 let grantStatus: Array<number> = data.authResults; 274 let length: number = grantStatus.length; 275 for (let i = 0; i < length; i++) { 276 if (grantStatus[i] === 0) { 277 // If the user has granted the permission, the application can access the Calendar. 278 } else { 279 // If the user has not granted the permission, display a message indicating that user authorization is required, and direct the user to the Settings page to set the permission. 280 return; 281 } 282 } 283 // The authorization is successful. 284 }).catch((err: BusinessError) => { 285 console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); 286 }) 287 } 288 289 // Page display. 290 build() { 291 // ... 292 } 293 } 294 ``` 295 2964. Perform subsequent operations based on the authorization result. 297 298 After [requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9) is called, the application waits for the user authorization result. If the user has granted the permission, the application can access the Calendar. If the user has not granted the permission, a message will be displayed indicating that user authorization is required, and the user is directed to **Settings** to set the permission. 299 300 The ArkTS syntax does not support direct use of **globalThis**. A singleton map is required to enable the use of **globalThis**. You need to perform the following operations: 301 302 a. Import the created singleton object **GlobalThis** to **EntryAbility.ets**. 303 ```typescript 304 import {GlobalThis} from '../utils/globalThis'; // Set based on the path of globalThis.ets. 305 ``` 306 b. Add the following to **onCreate**: 307 ```typescript 308 GlobalThis.getInstance().setContext('context', this.context); 309 ``` 310 311 > **NOTE** 312 > 313 > An alert will be generated when a **.ets** file is imported to a TS file. To prevent the alert, you need to change the file name extension of **EntryAbility.ts** to **EntryAbility.ets** and modify the file name extension in **module.json5**. 314 315 The sample code of **globalThis.ets** is as follows: 316 ```typescript 317 import { Context } from '@ohos.abilityAccessCtrl'; 318 319 // Construct a singleton object. 320 export class GlobalThis { 321 private constructor() {} 322 private static instance: GlobalThis; 323 private _uiContexts = new Map<string, Context>(); 324 325 public static getInstance(): GlobalThis { 326 if (!GlobalThis.instance) { 327 GlobalThis.instance = new GlobalThis(); 328 } 329 return GlobalThis.instance; 330 } 331 332 getContext(key: string): Context | undefined { 333 return this._uiContexts.get(key); 334 } 335 336 setContext(key: string, value: Context): void { 337 this._uiContexts.set(key, value); 338 } 339 340 // Set other content to be passed in the same way. 341 } 342 ``` 343 344 ```typescript 345 import { Context } from '@ohos.abilityAccessCtrl'; 346 import { BusinessError } from '@ohos.base'; 347 import Want from '@ohos.app.ability.Want'; 348 import { GlobalThis } from '../utils/globalThis'; 349 import common from '@ohos.app.ability.common'; 350 351 function openPermissionsInSystemSettings(): void { 352 let context: common.UIAbilityContext = GlobalThis.getInstance().getContext('context'); 353 let wantInfo: Want = { 354 action: 'action.settings.app.info', 355 parameters: { 356 settingsParamBundleName: 'com.example.myapplication' // Open the Details page of the application. 357 } 358 } 359 context.startAbility(wantInfo).then(() => { 360 // ... 361 }).catch((err: BusinessError) => { 362 // ... 363 }) 364 } 365 ``` 366 367### FA Model 368 369Call [requestPermissionsFromUser()](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7) to request user authorization. 370 371```ts 372import { BusinessError } from '@ohos.base'; 373import featureAbility from '@ohos.ability.featureAbility'; 374 375reqPermissions() { 376 let context = featureAbility.getContext(); 377 let array:Array<string> = ["ohos.permission.PERMISSION2"]; 378 // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. 379 context.requestPermissionsFromUser(array, 1).then(data => { 380 console.log("data:" + JSON.stringify(data)); 381 console.log("data permissions:" + JSON.stringify(data.permissions)); 382 console.log("data result:" + JSON.stringify(data.authResults)); 383 }, (err: BusinessError) => { 384 console.error('Failed to start ability', err.code); 385 }); 386} 387``` 388 389## Pre-authorizing user_grant Permissions 390 391The user_grant permissions can be pre-authorized in the [**install_list_permission.json** file](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/preinstall-config/install_list_permissions.json) in the **/system/etc/app/** directory of the device. When the device starts, it loads the **install_list_permission.json** file. When the applications are installed, the user_grant permissions are authorized. 392 393The **install_list_permissions.json** file contains the following fields: 394 395- **bundleName**: bundle name of the application. 396- **app_signature**: fingerprint information of the application. For details, see **Configuration in install_list_capability.json** in the [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). 397- **permissions**: The **name** field specifies the name of the user_grant permission to pre-authorize. The **userCancellable** field specifies whether the user can revoke the pre-authorization. The value **true** means the user can revoke the pre-authorization; the value **false** means the opposite. 398 399```json 400[ 401 // ... 402 { 403 "bundleName": "com.example.myapplication", // Bundle name. 404 "app_signature": ["****"], // Fingerprint information. 405 "permissions":[ 406 { 407 "name": "ohos.permission.PERMISSION_X", // Permission to pre-authorize. 408 "userCancellable": false // The user cannot revoke the authorization. 409 }, 410 { 411 "name": "ohos.permission.PERMISSION_X", // Permission to pre-authorize. 412 "userCancellable": true // The user can revoke the authorization. 413 } 414 ] 415 } 416] 417```