1 /*
<lambda>null2 * Copyright (C) 2023 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
17 package com.android.permissioncontroller.role.ui.wear
18
19 import android.content.pm.ApplicationInfo
20 import android.util.Pair
21 import androidx.compose.foundation.layout.Spacer
22 import androidx.compose.foundation.layout.height
23 import androidx.compose.runtime.Composable
24 import androidx.compose.runtime.getValue
25 import androidx.compose.runtime.livedata.observeAsState
26 import androidx.compose.runtime.mutableStateOf
27 import androidx.compose.runtime.remember
28 import androidx.compose.runtime.setValue
29 import androidx.compose.ui.Modifier
30 import androidx.compose.ui.platform.testTag
31 import androidx.compose.ui.res.stringResource
32 import androidx.compose.ui.unit.dp
33 import androidx.wear.compose.material.ChipDefaults
34 import androidx.wear.compose.material.MaterialTheme
35 import com.android.permissioncontroller.R
36 import com.android.permissioncontroller.permission.ui.wear.elements.Chip
37 import com.android.permissioncontroller.permission.ui.wear.elements.ListFooter
38 import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
39 import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChip
40 import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
41 import com.android.permissioncontroller.permission.ui.wear.elements.toggleChipBackgroundColors
42 import com.android.permissioncontroller.role.ui.ManageRoleHolderStateLiveData
43
44 @Composable
45 fun WearRequestRoleScreen(
46 helper: WearRequestRoleHelper,
47 onSetAsDefault: (Boolean, String?) -> Unit,
48 onCanceled: () -> Unit
49 ) {
50 val roleLiveData = helper.viewModel.roleLiveData.observeAsState(emptyList())
51 val manageRoleHolderState =
52 helper.viewModel.manageRoleHolderStateLiveData.observeAsState(
53 ManageRoleHolderStateLiveData.STATE_WORKING
54 )
55 val dontAskAgain = helper.wearViewModel.dontAskAgain.observeAsState(false)
56 val selectedPackageName = helper.wearViewModel.selectedPackageName.observeAsState(null)
57 var isLoading by remember { mutableStateOf(true) }
58
59 if (isLoading && roleLiveData.value.isNotEmpty()) {
60 helper.initializeHolderPackageName(roleLiveData.value)
61 helper.initializeSelectedPackageName()
62 }
63
64 val onCheckedChanged: (Boolean, String?, Boolean) -> Unit = { checked, packageName, isHolder ->
65 if (checked) {
66 helper.wearViewModel.selectedPackageName.value = packageName
67 helper.wearViewModel.isHolderChecked = isHolder
68 }
69 }
70
71 val onDontAskAgainCheckedChanged: (Boolean) -> Unit = { checked ->
72 helper.wearViewModel.dontAskAgain.value = checked
73 if (checked) {
74 helper.initializeSelectedPackageName()
75 }
76 }
77
78 WearRequestRoleContent(
79 isLoading,
80 helper,
81 roleLiveData.value,
82 manageRoleHolderState.value == ManageRoleHolderStateLiveData.STATE_IDLE,
83 dontAskAgain.value,
84 selectedPackageName.value,
85 onCheckedChanged,
86 onDontAskAgainCheckedChanged,
87 onSetAsDefault,
88 onCanceled
89 )
90
91 if (isLoading && roleLiveData.value.isNotEmpty()) {
92 isLoading = false
93 }
94 }
95
96 @Composable
WearRequestRoleContentnull97 internal fun WearRequestRoleContent(
98 isLoading: Boolean,
99 helper: WearRequestRoleHelper,
100 qualifyingApplications: List<Pair<ApplicationInfo, Boolean>>,
101 enabled: Boolean,
102 dontAskAgain: Boolean,
103 selectedPackageName: String?,
104 onCheckedChanged: (Boolean, String?, Boolean) -> Unit,
105 onDontAskAgainCheckedChanged: (Boolean) -> Unit,
106 onSetAsDefault: (Boolean, String?) -> Unit,
107 onCanceled: () -> Unit
108 ) {
109 ScrollableScreen(
110 image = helper.getIcon(),
111 title = helper.getTitle(),
112 showTimeText = false,
113 isLoading = isLoading
114 ) {
115 helper.getNonePreference(qualifyingApplications, selectedPackageName)?.let {
116 item {
117 ToggleChip(
118 label = it.label,
119 icon = it.icon,
120 enabled = enabled && it.enabled,
121 checked = it.checked,
122 onCheckedChanged = { checked ->
123 run { onCheckedChanged(checked, it.packageName, it.isHolder) }
124 },
125 toggleControl = ToggleChipToggleControl.Radio,
126 labelMaxLine = Integer.MAX_VALUE
127 )
128 }
129 it.subTitle?.let { subTitle -> item { ListFooter(description = subTitle) } }
130 }
131
132 for (pref in helper.getPreferences(qualifyingApplications, selectedPackageName)) {
133 item {
134 ToggleChip(
135 label = pref.label,
136 icon = pref.icon,
137 enabled = enabled && pref.enabled,
138 checked = pref.checked,
139 onCheckedChanged = { checked ->
140 run { onCheckedChanged(checked, pref.packageName, pref.isHolder) }
141 },
142 toggleControl = ToggleChipToggleControl.Radio,
143 )
144 }
145 pref.subTitle?.let { subTitle -> item { ListFooter(description = subTitle) } }
146 }
147
148 if (helper.showDontAskButton()) {
149 item {
150 ToggleChip(
151 checked = dontAskAgain,
152 enabled = enabled,
153 onCheckedChanged = { checked -> run { onDontAskAgainCheckedChanged(checked) } },
154 label = stringResource(R.string.request_role_dont_ask_again),
155 toggleControl = ToggleChipToggleControl.Checkbox,
156 colors = toggleChipBackgroundColors(),
157 modifier =
158 Modifier.testTag("com.android.permissioncontroller:id/dont_ask_again"),
159 )
160 }
161 }
162
163 item { Spacer(modifier = Modifier.height(14.dp)) }
164
165 item {
166 Chip(
167 label = stringResource(R.string.request_role_set_as_default),
168 textColor = MaterialTheme.colors.background,
169 colors = ChipDefaults.primaryChipColors(),
170 enabled = helper.shouldSetAsDefaultEnabled(enabled),
171 onClick = { onSetAsDefault(dontAskAgain, selectedPackageName) },
172 modifier = Modifier.testTag("android:id/button1"),
173 )
174 }
175 item {
176 Chip(
177 label = stringResource(R.string.cancel),
178 enabled = enabled,
179 onClick = { onCanceled() },
180 modifier = Modifier.testTag("android:id/button2"),
181 )
182 }
183 }
184 }
185