improvement(Android): If credentials feature is not supported then show a note to a user

This commit is contained in:
Artem Chepurnoy 2024-07-08 09:13:38 +03:00
parent 74ef9a34ef
commit bee31a26ed
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
3 changed files with 40 additions and 6 deletions

View File

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<!-- Passkeys -->
<uses-feature
android:name="android.software.credentials"
android:required="false" />
<!-- <!--
I need this permission to be able to check if linked app is installed on the I need this permission to be able to check if linked app is installed on the
system or not. --> system or not. -->

View File

@ -1,26 +1,32 @@
package com.artemchep.keyguard.feature.home.settings.component package com.artemchep.keyguard.feature.home.settings.component
import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Key import androidx.compose.material.icons.outlined.Key
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.credentials.CredentialManager import androidx.credentials.CredentialManager
import com.artemchep.keyguard.common.io.ioEffect import com.artemchep.keyguard.common.io.ioEffect
import com.artemchep.keyguard.common.io.launchIn import com.artemchep.keyguard.common.io.launchIn
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.res.* import com.artemchep.keyguard.res.*
import com.artemchep.keyguard.ui.FlatItem import com.artemchep.keyguard.ui.FlatItem
import com.artemchep.keyguard.ui.FlatSimpleNote
import com.artemchep.keyguard.ui.SimpleNote
import com.artemchep.keyguard.ui.icons.ChevronIcon import com.artemchep.keyguard.ui.icons.ChevronIcon
import com.artemchep.keyguard.ui.icons.icon import com.artemchep.keyguard.ui.icons.icon
import org.jetbrains.compose.resources.stringResource import com.artemchep.keyguard.ui.theme.Dimens
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import org.jetbrains.compose.resources.stringResource
import org.kodein.di.DirectDI import org.kodein.di.DirectDI
import org.kodein.di.instance import org.kodein.di.instance
@ -58,12 +64,22 @@ fun settingCredentialProviderProvider(
.create(context) .create(context)
.createSettingsPendingIntent() .createSettingsPendingIntent()
} }
val hasFeature = remember(context) {
val pm = context.packageManager
pm.hasSystemFeature(PackageManager.FEATURE_CREDENTIALS)
}
SettingCredentialProvider( SettingCredentialProvider(
onClick = { onClick = if (hasFeature) {
ioEffect(Dispatchers.Main.immediate) { // lambda
pi.send() {
}.launchIn(windowCoroutineScope) ioEffect(Dispatchers.Main.immediate) {
pi.send()
}.launchIn(windowCoroutineScope)
}
} else {
null
}, },
hasFeature = hasFeature,
) )
} }
flowOf(item) flowOf(item)
@ -72,6 +88,7 @@ fun settingCredentialProviderProvider(
@Composable @Composable
private fun SettingCredentialProvider( private fun SettingCredentialProvider(
onClick: (() -> Unit)?, onClick: (() -> Unit)?,
hasFeature: Boolean,
) { ) {
FlatItem( FlatItem(
leading = icon<RowScope>(Icons.Outlined.Key), leading = icon<RowScope>(Icons.Outlined.Key),
@ -90,4 +107,16 @@ private fun SettingCredentialProvider(
}, },
onClick = onClick, onClick = onClick,
) )
if (!hasFeature) {
FlatSimpleNote(
modifier = Modifier
.padding(
top = 8.dp,
bottom = 8.dp,
start = Dimens.horizontalPadding * 1 + 24.dp,
),
type = SimpleNote.Type.INFO,
text = stringResource(Res.string.pref_item_credential_provider_no_feature_note),
)
}
} }

View File

@ -1007,6 +1007,7 @@
<string name="pref_item_crash_title">Crash</string> <string name="pref_item_crash_title">Crash</string>
<string name="pref_item_credential_provider_title">Credential provider</string> <string name="pref_item_credential_provider_title">Credential provider</string>
<string name="pref_item_credential_provider_text">Passkeys, passwords and data services</string> <string name="pref_item_credential_provider_text">Passkeys, passwords and data services</string>
<string name="pref_item_credential_provider_no_feature_note">The device doesn't support retrieval of user credentials via integration with credential providers. Contact the manufacturer for more information.</string>
<string name="pref_item_privacy_policy_title">Privacy policy</string> <string name="pref_item_privacy_policy_title">Privacy policy</string>
<string name="pref_item_contact_us_title">Contact us</string> <string name="pref_item_contact_us_title">Contact us</string>
<string name="pref_item_experimental_title">Experimental</string> <string name="pref_item_experimental_title">Experimental</string>