Before using any of the Home APIs for Android, the app must have permission to access devices in the user's home, referred to in the API as*the structure*. With the Permissions API, the user can, using their Google Account, grant Home APIs apps access to devices in their home.
| **Note:** Permission grants are made on a structure-by-structure basis.

## Integrate the Permissions API

Before continuing, make sure you have followed[Initialize the home on Android](https://developers.home.google.com/apis/android/initialize). The`homeManager`instance from that step is used in all Permissions examples here.
| **Tip:** See the Sample App for examples of Permissions API calls.

First, register an[`ActivityResultCaller`](https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller)with the SDK. For example, this is how the Sample App handles it:  

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        homeManager.registerActivityResultCallerForPermissions(this)
      }

### Check for permissions

Prior to requesting permissions, we recommend you check to see whether the user of the app has already granted consent to access the structure. To do so, call the[`hasPermissions()`](https://developers.home.google.com/reference/kotlin/com/google/home/Home#hasPermissions())method of the Home instance to obtain a`Flow`of[`PermissionsState`](https://developers.home.google.com/reference/kotlin/com/google/home/PermissionsState)values:  

    val permissionsReadyState =
    homeManager.hasPermissions().collect { state ->
        when (state) {
          PermissionsState.GRANTED -> println("Permissions granted, no need to request permissions")
          PermissionsState.PERMISSIONS_STATE_UNAVAILABLE ->
              println("Permissions state unavailable, request permissions")

          PermissionsState.NOT_GRANTED ->
              println("OAuth permission is enabled but not granted yet, request permissions")

          PermissionsState.PERMISSIONS_STATE_UNINITIALIZED -> println(
              "Permissions state is not initialized yet. Clients should wait for another status update"
          )
          else ->
              throw IllegalStateException("""
                HomeClient.hasPermissions state should be PermissionsState.GRANTED,
                PermissionState.PERMISSIONS_STATE_UNINITIALIZED, or
                PermissionsState.PERMISSIONS_STATE_UNAVAILABLE. Actual state: $state
              """.trimIndent())
        }
    }

If the check returns a`PermissionsState`of`NOT_GRANTED`or`PERMISSIONS_STATE_UNAVAILABLE`, it means that either the user or the application lacks access to the structure. If the check returns a`PermissionsState`of`GRANTED`but a subsequent call to`structures()`returns no structures, then either the user has revoked access to the app through theGoogle Home app (GHA)settings page, or the user lacks the required access.

### Request permissions

Permission must be granted to your app in order to access structures and devices within a given structure.

<br />

| **Note:**An application can only be granted permission to one structure at any given time.

<br />

If the user has not already granted permissions, use the[`requestPermissions()`](https://developers.home.google.com/reference/kotlin/com/google/home/Home#requestPermissions())method of the Home instance to launch the Permissions UI and process the result:  

    fun requestPermissions(scope: CoroutineScope, onShowSnackbar: (String) -> Unit) {
      scope.launch {
        val result =
          try {
            homeManager.requestPermissions()
          } catch (e: HomeException) {
            PermissionsResult(
              PermissionsResultStatus.ERROR,
              "Got HomeException with error: ${e.message}",
            )
          }
        when (result.status) {
          PermissionsResultStatus.SUCCESS -> {
            Log.i(TAG, "Permissions successfully granted.")
          }
          PermissionsResultStatus.CANCELLED -> {
            Log.i(TAG, "User cancelled Permissions flow.")
            onShowSnackbar("User cancelled Permissions flow")
          }
          else -> {
            Log.e(
              TAG,
              "Failed to grant permissions with error: ${result.status}, ${result.errorMessage}",
            )
            onShowSnackbar("Failed to grant permissions with error: ${result.errorMessage}")
          }
        }
      }
    }

| **Tip:** The[`PermissionsManager`](https://github.com/google-home/google-home-api-sample-app-android/blob/a4312a3b6226a0b49396a5285a5b0981087e4b93/app/src/main/java/com/example/googlehomeapisampleapp/PermissionsManager.kt)class in the Sample App illustrates how to handle the permission flow.

For the Permissions UI to properly launch, you must have already[set up OAuth](https://developers.home.google.com/apis/android/oauth)for your app.

## Grant permissions

Now you should be able to run your app and have a user grant permissions. The type of users that can grant permission, and the device types that are available to grant permissions for, will differ depending on whether you have registered your app in theGoogle Home Developer Console.

Developer Consoleregistration is required to publish an app using the Home APIs. It is not required to test and use the Home APIs.
| **Important:**The Google Home Developer Console is not yet available for registration.

**If an app is not registered in theDeveloper Console** , it will be in an*unverified*state. This is recommended for testing use of the Home APIs:

- Only users[registered as test users in the OAuth console](https://developers.home.google.com/apis/android/oauth#consent)can grant permissions for the app. There is a limit of 100 test users for an unverified app.

- An unverified app will have access to devices of any device types that are supported by OAuth for the Home APIs (the list of device types in theDeveloper Console). All devices in a structure will be granted.

**If an app is registered in theDeveloper Console** and has been approved for access to one or more device types, and[brand verification has been completed for OAuth](https://developers.google.com/identity/protocols/oauth2/production-readiness/brand-verification), it will be in a*verified*state. This state is required for launching an app to production:

- Test user limits no longer apply. Any user can grant permission to the app.
- The user can only grant permission to the device types that were approved in theDeveloper Console.

Now that OAuth is set up, the app's call to`requestPermissions()`triggers the following dialogs:

1. The user is prompted to select the Google Account they want to use.
2. The user is prompted to select the structure they want to grant the app access to.
   1. For an unverified app, all device types supported by the Home APIs are available to the app.
   2. For a verified app, the user can grant permission to only the device types that have been approved inDeveloper Console.
   3. For sensitive device types that the app has access to manage, the user can restrict access on a per-device basis. For example, if a user has three locks, they can grant access to only one of those locks.

- ![OAuth consent - select account](https://developers.home.google.com/static/apis/images/apis-oauth-choose-account.png)
- ![OAuth consent - link devices 01](https://developers.home.google.com/static/apis/images/apis-oauth-link-account_01.png)
- ![OAuth consent - link device 02](https://developers.home.google.com/static/apis/images/apis-oauth-link-account_02.png)
**Figure 1**: Example OAuth consent flow

Once permission has been granted, the app can use the Home APIs to read the state of and control the devices in the structure. If the user doesn't grant permission to the app for a particular device type or sensitive device, the app won't be able to use the Home APIs to access, control, or automate it.

### Change permissions

To grant permission to access devices in a different structure, the account picker can be launched to allow the user to pick the Google Account and structure to switch to. During this process, the user will be presented with the consent screen again, even if consent was granted previously.

This can be done by calling`requestPermissions()`again with the`forceLaunch`flag set to`true`:  

    homeManager.requestPermissions(forceLaunch=true)

### Revoke permissions

Users can revoke previously-granted access:

1. Through the[Google MyAccounts page](https://myaccount.google.com/)**\> Data \& privacy \> Third-party apps \& services**. This will revoke the OAuth token that was issued when initial consent was granted, and will revoke access to any instance of the app that the user was using across all surfaces (phones) and structures.

   The user may be directed with a deep link to the**Third-party apps \& services**sub-page using the following URL scheme:  

       https://myaccount.google.com/connections/link?project_number=<var translate="no">Cloud project_number</var>

2. Through the**GHA\> Settings \> Linked Apps** page. Clicking onsettingsin theGHAwill take you to the**Settings** page. From there, click the**Linked Apps**tile which takes you to a page that looks similar to the consent screen. From this page the user can remove access to the app. The user can use this same page to change which device types or specific sensitive devices are accessible to the app.

## OkGoogle permissions

The[`okGoogle`](https://developers.home.google.com/reference/kotlin/com/google/home/google/AssistantFulfillmentTrait.OkGoogleCommand)command is a device-level command and can be used to automate any device in the structure. However, a Home APIs app may not have access to every device. The following table describes how permissions are enforced in such cases.

|                     Automation                      |                                                                                  Trait                                                                                  |                                                                                                                                                                                                                                                       Permissions enforcement                                                                                                                                                                                                                                                       |
|:---------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------:|: :|
| At 10:00pm, broadcast "Bedtime" on bedroom speaker. |              ` `[AssistantBroadcastTrait](https://developers.home.google.com/reference/kotlin/com/google/home/google/AssistantBroadcastTrait)` `on device.              |                                                                                                                             **Automation creation** : - The broadcast device must be an Assistant device. - The app and user must have access to the device on which the broadcast occurs. **Automation execution** : - The app and user must have access to the device on which the broadcast occurs.                                                                                                                              |
|   At 10:00pm, broadcast "Bedtime" on all devices    |            ` `[AssistantBroadcastTrait](https://developers.home.google.com/reference/kotlin/com/google/home/google/AssistantBroadcastTrait)` `on structure.             |                                                                                                                                **Automation creation** : - There must be at least one Assistant device in the structure that the app and user have access to. - The app and user must have access to the structure. **Automation execution** : - The app and user must have access to the structure.                                                                                                                                |
|            At 10:00pm, "play some music"            | ` `[AssistantFulfillmentTrait.OkGoogleCommand](https://developers.home.google.com/reference/kotlin/com/google/home/google/AssistantFulfillmentTrait.OkGoogleCommand)` ` |                                                                                                                                          **Automation creation** : - The app and user must have access to the devices to which the automation issues commands. **Automation execution** : - The app and user must have access to the devices to which the the automation issues commands.                                                                                                                                           |
|       Whenever someone says "play some music"       |           ` `[VoiceStarterTrait.OkGoogleEvent](https://developers.home.google.com/reference/kotlin/com/google/home/google/VoiceStarterTrait.OkGoogleEvent)` `           | **Automation creation** : - The app and user must have access to the structure. An Automation doesn't require an Assistant device to pass validation or to run, because any user with access to the structure may use their phone (using the same Google Account) to engage with Assistant and trigger the VoiceStarter. **Automation execution** : - The app doesn't require permission to access the device which starts the automation. - The app and user must have permission to access the device on which the action occurs. |

## Guidance if user revokes full permissions

If the user revokes full permissions, all existing automations will stop working. Also, if the user revokes access to specific devices, then starters, conditions, and actions associated with those devices will stop working.

**Each time the app starts, be sure to check that the permissions are still in effect. If they have been revoked, then be sure that all previous data are removed, including any data cached in the application.**