• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.jetpackcamera.permissions
17 
18 import android.Manifest
19 import android.util.Log
20 import androidx.activity.compose.rememberLauncherForActivityResult
21 import androidx.activity.result.contract.ActivityResultContracts
22 import androidx.compose.runtime.Composable
23 import androidx.compose.runtime.LaunchedEffect
24 import androidx.compose.runtime.collectAsState
25 import androidx.compose.runtime.getValue
26 import androidx.compose.ui.Modifier
27 import androidx.hilt.navigation.compose.hiltViewModel
28 import com.google.accompanist.permissions.ExperimentalPermissionsApi
29 import com.google.accompanist.permissions.MultiplePermissionsState
30 import com.google.accompanist.permissions.rememberMultiplePermissionsState
31 import com.google.accompanist.permissions.rememberPermissionState
32 import com.google.jetpackcamera.permissions.ui.PermissionTemplate
33 
34 private const val TAG = "PermissionsScreen"
35 
36 @OptIn(ExperimentalPermissionsApi::class)
37 @Composable
38 fun PermissionsScreen(
39     shouldRequestAudioPermission: Boolean,
40     onAllPermissionsGranted: () -> Unit,
41     openAppSettings: () -> Unit
42 ) {
43     val permissionStates = rememberMultiplePermissionsState(
44         permissions = if (shouldRequestAudioPermission) {
45             listOf(
46                 Manifest.permission.CAMERA,
47                 Manifest.permission.RECORD_AUDIO
48             )
49         } else {
50             listOf(
51                 Manifest.permission.CAMERA
52             )
53         }
54     )
55     PermissionsScreen(
56         permissionStates = permissionStates,
57         onAllPermissionsGranted = onAllPermissionsGranted,
58         openAppSettings = openAppSettings
59     )
60 }
61 
62 /**
63  * Permission prompts screen.
64  * Camera permission will always prompt when disabled, and the app cannot be used otherwise
65  * if optional settings have not yet been declined by the user, then they will be prompted as well
66  */
67 @OptIn(ExperimentalPermissionsApi::class)
68 @Composable
PermissionsScreennull69 fun PermissionsScreen(
70     modifier: Modifier = Modifier,
71     onAllPermissionsGranted: () -> Unit,
72     openAppSettings: () -> Unit,
73     permissionStates: MultiplePermissionsState,
74     viewModel: PermissionsViewModel = hiltViewModel<
75         PermissionsViewModel,
76         PermissionsViewModel.Factory
77         > { factory -> factory.create(permissionStates) }
78 ) {
79     Log.d(TAG, "PermissionsScreen")
80     val permissionsUiState: PermissionsUiState by viewModel.permissionsUiState.collectAsState()
<lambda>null81     LaunchedEffect(permissionsUiState) {
82         if (permissionsUiState is PermissionsUiState.AllPermissionsGranted) {
83             onAllPermissionsGranted()
84         }
85     }
86 
87     if (permissionsUiState is PermissionsUiState.PermissionsNeeded) {
88         val permissionEnum =
89             (permissionsUiState as PermissionsUiState.PermissionsNeeded).currentPermission
90         val currentPermissionState =
91             rememberPermissionState(
92                 permission = permissionEnum.getPermission()
93             )
94 
95         val permissionLauncher = rememberLauncherForActivityResult(
96             contract = ActivityResultContracts.RequestPermission(),
permissionGrantednull97             onResult = { permissionGranted ->
98                 if (permissionGranted) {
99                     // remove from list
100                     viewModel.dismissPermission()
101                 } else if (permissionEnum.isOptional()) {
102                     viewModel.dismissPermission()
103                 }
104             }
105         )
106 
107         PermissionTemplate(
108             modifier = modifier,
109             permissionEnum = permissionEnum,
110             permissionState = currentPermissionState,
111             onSkipPermission = when (permissionEnum) {
112                 // todo: a prettier navigation to app settings.
113                 PermissionEnum.CAMERA -> null
114                 // todo: skip permission button functionality. currently need to go through the
115                 // prompt to skip
116                 else -> null // permissionsViewModel::dismissPermission
117             },
<lambda>null118             onRequestPermission = { permissionLauncher.launch(permissionEnum.getPermission()) },
119             onOpenAppSettings = openAppSettings
120         )
121     }
122 }
123