Skip to content

Commit

Permalink
improvement: Add a note for Chrome users to enable native autofill #680
Browse files Browse the repository at this point in the history
  • Loading branch information
AChep committed Oct 30, 2024
1 parent 2c4456d commit fdee777
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.artemchep.keyguard.res.*
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
Expand Down Expand Up @@ -316,7 +317,7 @@ fun produceAppPickerState(
}
}

val itemsFlow = getAppsFlow(context.context)
val itemsFlow = flowOfInstalledApps(context.context)
.combine(sortSink) { items, sort ->
val comparator = Comparator<AppInfo> { a, b ->
val result = sort.comparator.compare(a, b)
Expand Down Expand Up @@ -370,7 +371,17 @@ fun produceAppPickerState(
}
}

private fun getAppsFlow(
fun flowOfInstalledAppsAnyOf(
context: Context,
packageNames: Iterable<String>,
) = flowOfInstalledApps(context)
.map { installedApps ->
installedApps
.any { app -> app.packageName in packageNames }
}
.distinctUntilChanged()

fun flowOfInstalledApps(
context: Context,
) = broadcastFlow(
context = context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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.OpenInBrowser
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
Expand All @@ -23,6 +24,10 @@ 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.feature.apppicker.flowOfInstalledAppsAnyOf
import com.artemchep.keyguard.feature.navigation.LocalNavigationController
import com.artemchep.keyguard.feature.navigation.NavigationIntent
import com.artemchep.keyguard.platform.LeContext
import com.artemchep.keyguard.res.Res
import com.artemchep.keyguard.res.*
import com.artemchep.keyguard.ui.ExpandedIfNotEmpty
Expand All @@ -31,8 +36,9 @@ 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 kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import org.jetbrains.compose.resources.stringResource
import kotlinx.coroutines.flow.map
import org.kodein.di.DirectDI
import org.kodein.di.instance
import java.io.BufferedReader
Expand All @@ -43,13 +49,18 @@ actual fun settingAutofillProvider(
directDI: DirectDI,
): SettingComponent = settingAutofillProvider(
autofillService = directDI.instance(),
appContext = directDI.instance(),
)

fun settingAutofillProvider(
autofillService: AutofillService,
): SettingComponent = autofillService
.status()
.map { status ->
appContext: LeContext,
): SettingComponent =
combine(
autofillService
.status(),
flowOfIsChromiumInstalled(context = appContext.context),
) { status, isChromeInstalled ->
val platformWarning = when {
isMiui() -> AutofillPlatformWarning.Miui
else -> null
Expand Down Expand Up @@ -88,6 +99,12 @@ fun settingAutofillProvider(
},
platformWarning = platformWarning,
)

ExpandedIfNotEmpty(
valueOrNull = isChromeInstalled.takeIf { it },
) {
SettingAutofillChromeNativeAutofillWarning()
}
}
}

Expand Down Expand Up @@ -168,6 +185,37 @@ private fun SettingAutofillPlatformWarningMiui(
)
}

@Composable
private fun SettingAutofillChromeNativeAutofillWarning(
) {
FlatSimpleNote(
modifier = Modifier
.padding(
top = 8.dp,
bottom = 8.dp,
start = Dimens.horizontalPadding * 1 + 24.dp,
),
type = SimpleNote.Type.INFO,
title = stringResource(Res.string.pref_item_autofill_service_chrome_native_autofill_title),
text = stringResource(Res.string.pref_item_autofill_service_chrome_native_autofill_text),
trailing = {
val navController by rememberUpdatedState(LocalNavigationController.current)
IconButton(
onClick = {
val url = "https://android-developers.googleblog.com/2024/10/chrome-3p-autofill-services.html"
val intent = NavigationIntent.NavigateToBrowser(url)
navController.queue(intent)
},
) {
Icon(
imageVector = Icons.Outlined.OpenInBrowser,
contentDescription = null,
)
}
},
)
}

private sealed interface AutofillPlatformWarning {
data object Miui : AutofillPlatformWarning {
fun launchPermissionSettings(
Expand Down Expand Up @@ -196,6 +244,24 @@ private sealed interface AutofillPlatformWarning {
}
}

private fun flowOfIsChromiumInstalled(
context: Context,
): Flow<Boolean> {
val chromiumPackageNames = setOf(
"com.android.chrome",
"com.chrome.beta",
"com.chrome.canary",
"com.chrome.dev",
"com.google.android.apps.chrome",
"com.google.android.apps.chrome_dev",
"org.chromium.chrome",
)
return flowOfInstalledAppsAnyOf(
context,
packageNames = chromiumPackageNames,
)
}

private fun isMiui(): Boolean {
return !getSystemProperty("ro.miui.ui.version.name").isNullOrBlank()
}
Expand Down
4 changes: 4 additions & 0 deletions common/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,10 @@
<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_service_chrome_native_autofill_title">Chrome to support third-party autofill services natively</string>
<string name="pref_item_autofill_service_chrome_native_autofill_text">1. Open Chrome's Settings and tap Autofill Services
2. Choose Autofill using another service
3. Confirm and restart Chrome</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>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.artemchep.keyguard.ui

import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
Expand Down Expand Up @@ -58,6 +59,7 @@ fun FlatSimpleNote(
text: String? = null,
leading: (@Composable RowScope.() -> Unit)? = null,
trailing: (@Composable RowScope.() -> Unit)? = null,
content: (@Composable ColumnScope.() -> Unit)? = null,
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
) {
Expand Down Expand Up @@ -123,6 +125,9 @@ fun FlatSimpleNote(
color = textColor,
)
}
if (content != null) {
content()
}
},
trailing = trailing,
onClick = onClick,
Expand Down

0 comments on commit fdee777

Please sign in to comment.