Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do we want to call openAppSettings() if not granted? #1923

Open
github-actions bot opened this issue Jun 29, 2024 · 0 comments
Open

Do we want to call openAppSettings() if not granted? #1923

github-actions bot opened this issue Jun 29, 2024 · 0 comments
Labels

Comments

@github-actions
Copy link
Contributor

// TODO: Do we want to call openAppSettings() if not granted?


// Copyright 2024, Christopher Banes and the Tivi project contributors
// SPDX-License-Identifier: Apache-2.0

package app.tivi.core.permissions

import app.tivi.core.permissions.Permission.REMOTE_NOTIFICATION

interface PermissionsController {
  /**
   * Check is permission already granted and if not - request permission from user.
   *
   * @param permission what permission we want to provide
   */
  suspend fun providePermission(permission: Permission): PermissionState

  /**
   * @return true if permission already granted. In all other cases - false.
   */
  suspend fun isPermissionGranted(permission: Permission): Boolean

  /**
   * Returns current state of permission. Can be suspended because on
   * Android detection of `Denied`/`NotDetermined` requires a bound FragmentManager.
   *
   * @param permission state of what permission we want
   *
   * @return current state. On Android can't be `DeniedAlways` (except push notifications).
   * On iOS can't be `Denied`.
   * @see PermissionState for a detailed description.
   */
  suspend fun getPermissionState(permission: Permission): PermissionState

  /**
   * Open system UI of application settings to change permissions state
   */
  fun openAppSettings()
}

suspend fun PermissionsController.requestPermissionWithRetry(permission: Permission): PermissionState {
  var lastResult: PermissionState = getPermissionState(permission)
  for (index in 0 until 2) {
    if (lastResult.canRequest()) {
      lastResult = providePermission(permission)
    } else {
      break
    }
  }

  // TODO: Do we want to call openAppSettings() if not granted?

  return lastResult
}

suspend fun PermissionsController.performPermissionedAction(
  permission: Permission,
  block: suspend (PermissionState) -> Unit,
) {
  val permissionState = getPermissionState(permission)
  if (permissionState == PermissionState.Granted) {
    block(permissionState)
  } else {
    block(requestPermissionWithRetry(REMOTE_NOTIFICATION))
  }
}

enum class Permission {
  CAMERA,
  GALLERY,
  STORAGE,
  WRITE_STORAGE,
  LOCATION,
  COARSE_LOCATION,
  BACKGROUND_LOCATION,
  BLUETOOTH_LE,
  REMOTE_NOTIFICATION,
  RECORD_AUDIO,
  BLUETOOTH_SCAN,
  BLUETOOTH_ADVERTISE,
  BLUETOOTH_CONNECT,
  CONTACTS,
  MOTION,
}

enum class PermissionState {

  /**
   * Starting state for each permission.
   */
  NotDetermined,

  /**
   * Android-only. This could mean [NotDetermined] or [DeniedAlways], but the OS doesn't
   * expose which of the two it is in all scenarios.
   */
  NotGranted,

  Granted,

  /**
   * Android-only.
   */
  Denied,

  /**
   * On Android only applicable to Push Notifications.
   */
  DeniedAlways,
}

fun PermissionState.canRequest(): Boolean = when (this) {
  PermissionState.Granted -> false
  PermissionState.DeniedAlways -> false
  else -> true
}

@github-actions github-actions bot added the todo label Jun 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

0 participants