Show a warning on Xiaomi devices that it might need additional permission enabled for Autofill to work

This commit is contained in:
Artem Chepurnoy 2024-01-29 13:29:16 +02:00
parent be6f329b88
commit 13a223879b
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
2 changed files with 127 additions and 0 deletions

View File

@ -1,25 +1,42 @@
package com.artemchep.keyguard.feature.home.settings.component
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AutoAwesome
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import arrow.core.partially1
import com.artemchep.keyguard.android.closestActivityOrNull
import com.artemchep.keyguard.common.service.autofill.AutofillService
import com.artemchep.keyguard.common.service.autofill.AutofillServiceStatus
import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.ui.ExpandedIfNotEmpty
import com.artemchep.keyguard.ui.FlatItem
import com.artemchep.keyguard.ui.FlatSimpleNote
import com.artemchep.keyguard.ui.SimpleNote
import com.artemchep.keyguard.ui.icons.icon
import com.artemchep.keyguard.ui.theme.Dimens
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.flow.map
import org.kodein.di.DirectDI
import org.kodein.di.instance
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
actual fun settingAutofillProvider(
directDI: DirectDI,
@ -32,6 +49,11 @@ fun settingAutofillProvider(
): SettingComponent = autofillService
.status()
.map { status ->
val platformWarning = when {
isMiui() -> AutofillPlatformWarning.Miui
else -> null
}
// composable
SettingIi(
search = SettingIi.Search(
@ -63,6 +85,7 @@ fun settingAutofillProvider(
} else {
null
},
platformWarning = platformWarning,
)
}
}
@ -71,6 +94,7 @@ fun settingAutofillProvider(
private fun SettingAutofill(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
platformWarning: AutofillPlatformWarning?,
) {
FlatItem(
leading = icon<RowScope>(Icons.Outlined.AutoAwesome),
@ -93,4 +117,106 @@ private fun SettingAutofill(
},
onClick = onCheckedChange?.partially1(!checked),
)
ExpandedIfNotEmpty(
valueOrNull = platformWarning.takeIf { checked },
) {
SettingAutofillPlatformWarning(
platformWarning = it,
)
}
}
@Composable
private fun SettingAutofillPlatformWarning(
platformWarning: AutofillPlatformWarning,
) = when (platformWarning) {
is AutofillPlatformWarning.Miui -> {
SettingAutofillPlatformWarningMiui(
platformWarning = platformWarning,
)
}
}
@Composable
private fun SettingAutofillPlatformWarningMiui(
platformWarning: AutofillPlatformWarning.Miui,
) {
FlatSimpleNote(
modifier = Modifier
.padding(
top = 8.dp,
bottom = 8.dp,
start = Dimens.horizontalPadding * 1 + 24.dp,
),
type = SimpleNote.Type.INFO,
text = stringResource(Res.strings.pref_item_autofill_service_xiaomi_permission_note),
trailing = {
val updatedContext by rememberUpdatedState(LocalContext.current)
IconButton(
onClick = {
AutofillPlatformWarning.Miui.launchPermissionSettings(updatedContext)
},
) {
Icon(
imageVector = Icons.Outlined.Settings,
contentDescription = null,
)
}
},
)
}
private sealed interface AutofillPlatformWarning {
data object Miui : AutofillPlatformWarning {
fun launchPermissionSettings(
context: Context,
) {
val packageName = context.packageName
val intent = Intent("miui.intent.action.APP_PERM_EDITOR").apply {
setClassName(
"com.miui.securitycenter",
"com.miui.permcenter.permissions.PermissionsEditorActivity",
)
putExtra("extra_pkgname", packageName)
}
try {
context.startActivity(intent)
} catch (e: Exception) {
val genericIntent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.parse("package:$packageName"),
)
kotlin.runCatching {
context.startActivity(genericIntent)
}
}
}
}
}
private fun isMiui(): Boolean {
return !getSystemProperty("ro.miui.ui.version.name").isNullOrBlank()
}
private fun getSystemProperty(propName: String): String? {
val line: String
var input: BufferedReader? = null
try {
val p = Runtime.getRuntime().exec("getprop $propName")
input = BufferedReader(InputStreamReader(p.inputStream), 1024)
line = input.readLine()
input.close()
} catch (ex: IOException) {
return null
} finally {
if (input != null) {
try {
input.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
return line
}

View File

@ -917,6 +917,7 @@
<string name="pref_item_keep_screen_on_title">Keep the screen on while viewing items</string>
<string name="pref_item_autofill_service_title">Autofill service</string>
<string name="pref_item_autofill_service_text">Use the Android Autofill Framework to assist in filling login information into other apps on the device</string>
<string name="pref_item_autofill_service_xiaomi_permission_note">Some Xiaomi devices require you to manually allow the \"Display pop-up windows while running in the background\" permission. Please open the settings and verify that it is granted.</string>
<string name="pref_item_autofill_auto_copy_otp_title">Auto-copy one-time passwords</string>
<string name="pref_item_autofill_auto_copy_otp_text">When filling a login information, automatically copy one-time passwords</string>
<string name="pref_item_autofill_inline_suggestions_title">Inline suggestions</string>