• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![](figures/permission-read_calendar.png)
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```