| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 1 | page.title=Permissions |
| 2 | @jd:body |
| 3 | |
| 4 | <div id="qv-wrapper"> |
| 5 | <div id="qv"> |
| 6 | |
| 7 | <h2>In this document</h2> |
| 8 | <ol> |
| 9 | <li><a href="#arch">Security Architecture</a></li> |
| 10 | <li><a href="#signing">Application Signing</a></li> |
| 11 | <li><a href="#userid">User IDs and File Access</a></li> |
| 12 | <li><a href="#permissions">Using Permissions</a></li> |
| 13 | <li><a href="#declaring">Declaring and Enforcing Permissions</a> |
| 14 | <ol> |
| 15 | <li><a href="#manifest">...in AndroidManifest.xml</a></li> |
| 16 | <li><a href="#broadcasts">...when Sending Broadcasts</a></li> |
| 17 | <li><a href="#enforcement">Other Permission Enforcement</a></li> |
| 18 | </ol></li> |
| 19 | <li><a href="#uri">URI Permissions</a></li> |
| 20 | </ol> |
| 21 | </div> |
| 22 | </div> |
| 23 | <p>This document describes how application developers can use the |
| 24 | security features provided by Android. A more general <a |
| 25 | href="http://source.android.com/tech/security/index.html"> Android Security |
| 26 | Overview</a> is provided in the Android Open Source Project.</p> |
| 27 | |
| 28 | <p>Android is a privilege-separated operating system, in which each |
| 29 | application runs with a distinct system identity (Linux user ID and group |
| 30 | ID). Parts of the system are also separated into distinct identities. |
| 31 | Linux thereby isolates applications from each other and from the system.</p> |
| 32 | |
| 33 | <p>Additional finer-grained security features are provided through a |
| 34 | "permission" mechanism that enforces restrictions on the specific operations |
| 35 | that a particular process can perform, and per-URI permissions for granting |
| 36 | ad-hoc access to specific pieces of data.</p> |
| 37 | |
| 38 | <a name="arch"></a> |
| 39 | <h2>Security Architecture</h2> |
| 40 | |
| 41 | <p>A central design point of the Android security architecture is that no |
| 42 | application, by default, has permission to perform any operations that would |
| 43 | adversely impact other applications, the operating system, or the user. This |
| 44 | includes reading or writing the user's private data (such as contacts or |
| 45 | e-mails), reading or writing another application's files, performing |
| 46 | network access, keeping the device awake, etc.</p> |
| 47 | |
| 48 | <p>Because Android sandboxes applications from each other, applications |
| 49 | must explicitly share resources and data. They do this by declaring the |
| 50 | <em>permissions</em> they need for additional capabilities not provided by |
| 51 | the basic sandbox. Applications statically declare the permissions they |
| 52 | require, and the Android system prompts the user for consent at the time the |
| 53 | application is installed. Android has no mechanism for granting permissions |
| 54 | dynamically (at run-time) because it complicates the user experience to the |
| 55 | detriment of security.</p> |
| 56 | |
| 57 | <p>The application sandbox does not depend on the technology used to build |
| 58 | an application. In particular the Dalvik VM is not a security boundary, and |
| 59 | any app can run native code (see <a href="/sdk/ndk/index.html">the Android |
| 60 | NDK</a>). All types of applications — Java, native, and hybrid — |
| 61 | are sandboxed in the same way and have the same degree of security from each |
| 62 | other.</p> |
| 63 | |
| Scott Main | dc2c1a0 | 2012-12-18 16:07:36 -0800 | [diff] [blame] | 64 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 65 | <a name="signing"></a> |
| 66 | <h2>Application Signing</h2> |
| 67 | |
| 68 | <p>All Android applications (.apk files) must be signed with a certificate |
| 69 | whose private key is held by their developer. This certificate identifies |
| 70 | the author of the application. The certificate does <em>not</em> need to be |
| 71 | signed by a certificate authority: it is perfectly allowable, and typical, |
| 72 | for Android applications to use self-signed certificates. The purpose of |
| 73 | certificates in Android is to distinguish application authors. This allows |
| 74 | the system to grant or deny applications access to <a |
| 75 | href="/guide/topics/manifest/permission-element.html#plevel">signature-level |
| 76 | permissions</a> and to grant or deny an application's <a |
| 77 | href="/guide/topics/manifest/manifest-element.html#uid">request to be given |
| 78 | the same Linux identity</a> as another application.</p> |
| 79 | |
| 80 | <a name="userid"></a> |
| 81 | <h2>User IDs and File Access</h2> |
| 82 | |
| 83 | <p>At install time, Android gives each package a distinct Linux user ID. The |
| 84 | identity remains constant for the duration of the package's life on that |
| 85 | device. On a different device, the same package may have a different UID; |
| 86 | what matters is that each package has a distinct UID on a given device.</p> |
| 87 | |
| 88 | <p>Because security enforcement happens at the |
| 89 | process level, the code of any two packages can not normally |
| 90 | run in the same process, since they need to run as different Linux users. |
| 91 | You can use the {@link android.R.attr#sharedUserId} attribute in the |
| 92 | <code>AndroidManifest.xml</code>'s |
| 93 | {@link android.R.styleable#AndroidManifest manifest} tag of each package to |
| 94 | have them assigned the same user ID. By doing this, for purposes of security |
| 95 | the two packages are then treated as being the same application, with the same |
| 96 | user ID and file permissions. Note that in order to retain security, only two applications |
| 97 | signed with the same signature (and requesting the same sharedUserId) will |
| 98 | be given the same user ID.</p> |
| 99 | |
| 100 | <p>Any data stored by an application will be assigned that application's user |
| 101 | ID, and not normally accessible to other packages. When creating a new file |
| 102 | with {@link android.content.Context#getSharedPreferences}, |
| 103 | {@link android.content.Context#openFileOutput}, or |
| 104 | {@link android.content.Context#openOrCreateDatabase}, |
| 105 | you can use the |
| 106 | {@link android.content.Context#MODE_WORLD_READABLE} and/or |
| 107 | {@link android.content.Context#MODE_WORLD_WRITEABLE} flags to allow any other |
| 108 | package to read/write the file. When setting these flags, the file is still |
| 109 | owned by your application, but its global read and/or write permissions have |
| 110 | been set appropriately so any other application can see it.</p> |
| 111 | |
| 112 | |
| 113 | <a name="permissions"></a> |
| 114 | <h2>Using Permissions</h2> |
| 115 | |
| Scott Main | dc2c1a0 | 2012-12-18 16:07:36 -0800 | [diff] [blame] | 116 | <p>A basic Android application has no permissions associated with it by default, |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 117 | meaning it can not do anything that would adversely impact the user experience |
| 118 | or any data on the device. To make use of protected features of the device, |
| 119 | you must include in your <code>AndroidManifest.xml</code> one or more |
| 120 | <code>{@link android.R.styleable#AndroidManifestUsesPermission <uses-permission>}</code> |
| 121 | tags declaring the permissions that your application needs.</p> |
| 122 | |
| 123 | <p>For example, an application that needs to monitor incoming SMS messages would |
| 124 | specify:</p> |
| 125 | |
| 126 | <pre><manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| 127 | package="com.android.app.myapp" > |
| 128 | <uses-permission android:name="android.permission.RECEIVE_SMS" /> |
| 129 | ... |
| 130 | </manifest></pre> |
| 131 | |
| 132 | <p>At application install time, permissions requested by the application are |
| 133 | granted to it by the package installer, based on checks against the |
| 134 | signatures of the applications declaring those permissions and/or interaction |
| 135 | with the user. <em>No</em> checks with the user |
| 136 | are done while an application is running: it either was granted a particular |
| 137 | permission when installed, and can use that feature as desired, or the |
| 138 | permission was not granted and any attempt to use the feature will fail |
| 139 | without prompting the user.</p> |
| 140 | |
| 141 | <p>Often times a permission failure will result in a {@link |
| 142 | java.lang.SecurityException} being thrown back to the application. However, |
| 143 | this is not guaranteed to occur everywhere. For example, the {@link |
| 144 | android.content.Context#sendBroadcast} method checks permissions as data is |
| 145 | being delivered to each receiver, after the method call has returned, so you |
| 146 | will not receive an exception if there are permission failures. In almost all |
| 147 | cases, however, a permission failure will be printed to the system log.</p> |
| 148 | |
| 149 | <p>The permissions provided by the Android system can be found at {@link |
| 150 | android.Manifest.permission}. Any application may also define and enforce its |
| 151 | own permissions, so this is not a comprehensive list of all possible |
| 152 | permissions.</p> |
| 153 | |
| 154 | <p>A particular permission may be enforced at a number of places during your |
| 155 | program's operation:</p> |
| 156 | |
| 157 | <ul> |
| 158 | <li>At the time of a call into the system, to prevent an application from |
| 159 | executing certain functions.</li> |
| 160 | <li>When starting an activity, to prevent applications from launching |
| 161 | activities of other applications.</li> |
| 162 | <li>Both sending and receiving broadcasts, to control who can receive |
| 163 | your broadcast or who can send a broadcast to you.</li> |
| 164 | <li>When accessing and operating on a content provider.</li> |
| 165 | <li>Binding to or starting a service.</li> |
| 166 | </ul> |
| 167 | |
| 168 | |
| Scott Main | dc2c1a0 | 2012-12-18 16:07:36 -0800 | [diff] [blame] | 169 | |
| 170 | <div class="caution"> |
| 171 | <p><strong>Caution:</strong> Over time, |
| 172 | new restrictions may be added to the platform such that, in order |
| 173 | to use certain APIs, your app must request a permission that it previously did not need. |
| 174 | Because existing apps assume access to those APIs is freely available, |
| 175 | Android may apply the new permission request to the app's manifest to avoid |
| 176 | breaking the app on the new platform version. |
| 177 | Android makes the decision as to whether an app might need the permission based on |
| 178 | the value provided for the <a |
| 179 | href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> |
| 180 | attribute. If the value is lower than the version in which the permission was added, then |
| 181 | Android adds the permission.</p> |
| 182 | <p>For example, the {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission was |
| 183 | added in API level 4 to restrict access to the shared storage space. If your <a |
| 184 | href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> |
| 185 | is 3 or lower, this permission is added to your app on newer versions of Android.</p> |
| 186 | <p>Beware that if this happens to your app, your app listing on Google Play will show these |
| 187 | required permissions even though your app might not actually require them.</p> |
| 188 | <p>To avoid this and remove the default permissions you don't need, always update your <a |
| 189 | href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> |
| 190 | to be as high as possible. You can see which permissions were added with each release in the |
| 191 | {@link android.os.Build.VERSION_CODES} documentation.</p> |
| 192 | </div> |
| 193 | |
| 194 | |
| 195 | |
| Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 196 | <a name="declaring"></a> |
| 197 | <h2>Declaring and Enforcing Permissions</h2> |
| 198 | |
| 199 | <p>To enforce your own permissions, you must first declare them in your |
| 200 | <code>AndroidManifest.xml</code> using one or more |
| 201 | <code>{@link android.R.styleable#AndroidManifestPermission <permission>}</code> |
| 202 | tags.</p> |
| 203 | |
| 204 | <p>For example, an application that wants to control who can start one |
| 205 | of its activities could declare a permission for this operation as follows:</p> |
| 206 | |
| 207 | <pre><manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| 208 | package="com.me.app.myapp" > |
| 209 | <permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY" |
| 210 | android:label="@string/permlab_deadlyActivity" |
| 211 | android:description="@string/permdesc_deadlyActivity" |
| 212 | android:permissionGroup="android.permission-group.COST_MONEY" |
| 213 | android:protectionLevel="dangerous" /> |
| 214 | ... |
| 215 | </manifest></pre> |
| 216 | |
| 217 | <p>The {@link android.R.styleable#AndroidManifestPermission_protectionLevel |
| 218 | <protectionLevel>} attribute is required, telling the system how the |
| 219 | user is to be informed of applications requiring the permission, or who is |
| 220 | allowed to hold that permission, as described in the linked documentation.</p> |
| 221 | |
| 222 | <p>The {@link android.R.styleable#AndroidManifestPermission_permissionGroup |
| 223 | <permissionGroup>} attribute is optional, and only used to help the system display |
| 224 | permissions to the user. You will usually want to set this to either a standard |
| 225 | system group (listed in {@link android.Manifest.permission_group |
| 226 | android.Manifest.permission_group}) or in more rare cases to one defined by |
| 227 | yourself. It is preferred to use an existing group, as this simplifies the |
| 228 | permission UI shown to the user.</p> |
| 229 | |
| 230 | <p>Note that both a label and description should be supplied for the |
| 231 | permission. These are string resources that can be displayed to the user when |
| 232 | they are viewing a list of permissions |
| 233 | (<code>{@link android.R.styleable#AndroidManifestPermission_label android:label}</code>) |
| 234 | or details on a single permission ( |
| 235 | <code>{@link android.R.styleable#AndroidManifestPermission_description android:description}</code>). |
| 236 | The label should be short, a few words |
| 237 | describing the key piece of functionality the permission is protecting. The |
| 238 | description should be a couple sentences describing what the permission allows |
| 239 | a holder to do. Our convention for the description is two sentences, the first |
| 240 | describing the permission, the second warning the user of what bad things |
| 241 | can happen if an application is granted the permission.</p> |
| 242 | |
| 243 | <p>Here is an example of a label and description for the CALL_PHONE |
| 244 | permission:</p> |
| 245 | |
| 246 | <pre> |
| 247 | <string name="permlab_callPhone">directly call phone numbers</string> |
| 248 | <string name="permdesc_callPhone">Allows the application to call |
| 249 | phone numbers without your intervention. Malicious applications may |
| 250 | cause unexpected calls on your phone bill. Note that this does not |
| 251 | allow the application to call emergency numbers.</string> |
| 252 | </pre> |
| 253 | |
| 254 | <p>You can look at the permissions currently defined in the system with the |
| 255 | Settings app and the shell command <code>adb shell pm list permissions</code>. |
| 256 | To use the Settings app, go to Settings > Applications. Pick an app and |
| 257 | scroll down to see the permissions that the app uses. For developers, the adb '-s' |
| 258 | option displays the permissions in a form similar to how the user will see them:</p> |
| 259 | |
| 260 | <pre> |
| 261 | $ adb shell pm list permissions -s |
| 262 | All Permissions: |
| 263 | |
| 264 | Network communication: view Wi-Fi state, create Bluetooth connections, full |
| 265 | Internet access, view network state |
| 266 | |
| 267 | Your location: access extra location provider commands, fine (GPS) location, |
| 268 | mock location sources for testing, coarse (network-based) location |
| 269 | |
| 270 | Services that cost you money: send SMS messages, directly call phone numbers |
| 271 | |
| 272 | ...</pre> |
| 273 | |
| 274 | <a name="manifest"></a> |
| 275 | <h3>Enforcing Permissions in AndroidManifest.xml</h3> |
| 276 | |
| 277 | <p>High-level permissions restricting access to entire components of the |
| 278 | system or application can be applied through your |
| 279 | <code>AndroidManifest.xml</code>. All that this requires is including an {@link |
| 280 | android.R.attr#permission android:permission} attribute on the desired |
| 281 | component, naming the permission that will be used to control access to |
| 282 | it.</p> |
| 283 | |
| 284 | <p><strong>{@link android.app.Activity}</strong> permissions |
| 285 | (applied to the |
| 286 | {@link android.R.styleable#AndroidManifestActivity <activity>} tag) |
| 287 | restrict who can start the associated |
| 288 | activity. The permission is checked during |
| 289 | {@link android.content.Context#startActivity Context.startActivity()} and |
| 290 | {@link android.app.Activity#startActivityForResult Activity.startActivityForResult()}; |
| 291 | if the caller does not have |
| 292 | the required permission then {@link java.lang.SecurityException} is thrown |
| 293 | from the call.</p> |
| 294 | |
| 295 | <p><strong>{@link android.app.Service}</strong> permissions |
| 296 | (applied to the |
| 297 | {@link android.R.styleable#AndroidManifestService <service>} tag) |
| 298 | restrict who can start or bind to the |
| 299 | associated service. The permission is checked during |
| 300 | {@link android.content.Context#startService Context.startService()}, |
| 301 | {@link android.content.Context#stopService Context.stopService()} and |
| 302 | {@link android.content.Context#bindService Context.bindService()}; |
| 303 | if the caller does not have |
| 304 | the required permission then {@link java.lang.SecurityException} is thrown |
| 305 | from the call.</p> |
| 306 | |
| 307 | <p><strong>{@link android.content.BroadcastReceiver}</strong> permissions |
| 308 | (applied to the |
| 309 | {@link android.R.styleable#AndroidManifestReceiver <receiver>} tag) |
| 310 | restrict who can send broadcasts to the associated receiver. |
| 311 | The permission is checked <em>after</em> |
| 312 | {@link android.content.Context#sendBroadcast Context.sendBroadcast()} returns, |
| 313 | as the system tries |
| 314 | to deliver the submitted broadcast to the given receiver. As a result, a |
| 315 | permission failure will not result in an exception being thrown back to the |
| 316 | caller; it will just not deliver the intent. In the same way, a permission |
| 317 | can be supplied to |
| 318 | {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, String, android.os.Handler) |
| 319 | Context.registerReceiver()} |
| 320 | to control who can broadcast to a programmatically registered receiver. |
| 321 | Going the other way, a permission can be supplied when calling |
| 322 | {@link android.content.Context#sendBroadcast(Intent, String) Context.sendBroadcast()} |
| 323 | to restrict which BroadcastReceiver objects are allowed to receive the broadcast (see |
| 324 | below).</p> |
| 325 | |
| 326 | <p><strong>{@link android.content.ContentProvider}</strong> permissions |
| 327 | (applied to the |
| 328 | {@link android.R.styleable#AndroidManifestProvider <provider>} tag) |
| 329 | restrict who can access the data in |
| 330 | a {@link android.content.ContentProvider}. (Content providers have an important |
| 331 | additional security facility available to them called |
| 332 | <a href="#uri">URI permissions</a> which is described later.) |
| 333 | Unlike the other components, |
| 334 | there are two separate permission attributes you can set: |
| 335 | {@link android.R.attr#readPermission android:readPermission} restricts who |
| 336 | can read from the provider, and |
| 337 | {@link android.R.attr#writePermission android:writePermission} restricts |
| 338 | who can write to it. Note that if a provider is protected with both a read |
| 339 | and write permission, holding only the write permission does not mean |
| 340 | you can read from a provider. The permissions are checked when you first |
| 341 | retrieve a provider (if you don't have either permission, a SecurityException |
| 342 | will be thrown), and as you perform operations on the provider. Using |
| 343 | {@link android.content.ContentResolver#query ContentResolver.query()} requires |
| 344 | holding the read permission; using |
| 345 | {@link android.content.ContentResolver#insert ContentResolver.insert()}, |
| 346 | {@link android.content.ContentResolver#update ContentResolver.update()}, |
| 347 | {@link android.content.ContentResolver#delete ContentResolver.delete()} |
| 348 | requires the write permission. |
| 349 | In all of these cases, not holding the required permission results in a |
| 350 | {@link java.lang.SecurityException} being thrown from the call.</p> |
| 351 | |
| 352 | |
| 353 | <a name="broadcasts"></a> |
| 354 | <h3>Enforcing Permissions when Sending Broadcasts</h3> |
| 355 | |
| 356 | <p>In addition to the permission enforcing who can send Intents to a |
| 357 | registered {@link android.content.BroadcastReceiver} (as described above), you |
| 358 | can also specify a required permission when sending a broadcast. By calling {@link |
| 359 | android.content.Context#sendBroadcast(android.content.Intent,String) |
| 360 | Context.sendBroadcast()} with a |
| 361 | permission string, you require that a receiver's application must hold that |
| 362 | permission in order to receive your broadcast.</p> |
| 363 | |
| 364 | <p>Note that both a receiver and a broadcaster can require a permission. When |
| 365 | this happens, both permission checks must pass for the Intent to be delivered |
| 366 | to the associated target.</p> |
| 367 | |
| 368 | |
| 369 | <a name="enforcement"></a> |
| 370 | <h3>Other Permission Enforcement</h3> |
| 371 | |
| 372 | <p>Arbitrarily fine-grained permissions can be enforced at any call into a |
| 373 | service. This is accomplished with the {@link |
| 374 | android.content.Context#checkCallingPermission Context.checkCallingPermission()} |
| 375 | method. Call with a desired |
| 376 | permission string and it will return an integer indicating whether that |
| 377 | permission has been granted to the current calling process. Note that this can |
| 378 | only be used when you are executing a call coming in from another process, |
| 379 | usually through an IDL interface published from a service or in some other way |
| 380 | given to another process.</p> |
| 381 | |
| 382 | <p>There are a number of other useful ways to check permissions. If you have |
| 383 | the pid of another process, you can use the Context method {@link |
| 384 | android.content.Context#checkPermission(String, int, int) Context.checkPermission(String, int, int)} |
| 385 | to check a permission against that pid. If you have the package name of another |
| 386 | application, you can use the direct PackageManager method {@link |
| 387 | android.content.pm.PackageManager#checkPermission(String, String) |
| 388 | PackageManager.checkPermission(String, String)} |
| 389 | to find out whether that particular package has been granted a specific permission.</p> |
| 390 | |
| 391 | |
| 392 | <a name="uri"></a> |
| 393 | <h2>URI Permissions</h2> |
| 394 | |
| 395 | <p>The standard permission system described so far is often not sufficient |
| 396 | when used with content providers. A content provider may want to |
| 397 | protect itself with read and write permissions, while its direct clients |
| 398 | also need to hand specific URIs to other applications for them to operate on. |
| 399 | A typical example is attachments in a mail application. Access to the mail |
| 400 | should be protected by permissions, since this is sensitive user data. However, |
| 401 | if a URI to an image attachment is given to an image viewer, that image viewer |
| 402 | will not have permission to open the attachment since it has no reason to hold |
| 403 | a permission to access all e-mail.</p> |
| 404 | |
| 405 | <p>The solution to this problem is per-URI permissions: when starting an |
| 406 | activity or returning a result to an activity, the caller can set |
| 407 | {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION |
| 408 | Intent.FLAG_GRANT_READ_URI_PERMISSION} and/or |
| 409 | {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION |
| 410 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION}. This grants the receiving activity |
| 411 | permission access the specific data URI in the Intent, regardless of whether |
| 412 | it has any permission to access data in the content provider corresponding |
| 413 | to the Intent.</p> |
| 414 | |
| 415 | <p>This mechanism allows a common capability-style model where user interaction |
| 416 | (opening an attachment, selecting a contact from a list, etc) drives ad-hoc |
| 417 | granting of fine-grained permission. This can be a key facility for reducing |
| 418 | the permissions needed by applications to only those directly related to their |
| 419 | behavior.</p> |
| 420 | |
| 421 | <p>The granting of fine-grained URI permissions does, however, require some |
| 422 | cooperation with the content provider holding those URIs. It is strongly |
| 423 | recommended that content providers implement this facility, and declare that |
| 424 | they support it through the |
| 425 | {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions |
| 426 | android:grantUriPermissions} attribute or |
| 427 | {@link android.R.styleable#AndroidManifestGrantUriPermission |
| 428 | <grant-uri-permissions>} tag.</p> |
| 429 | |
| 430 | <p>More information can be found in the |
| 431 | {@link android.content.Context#grantUriPermission Context.grantUriPermission()}, |
| 432 | {@link android.content.Context#revokeUriPermission Context.revokeUriPermission()}, and |
| 433 | {@link android.content.Context#checkUriPermission Context.checkUriPermission()} |
| 434 | methods.</p> |
| 435 | |