mirror of
https://github.com/bitwarden/android.git
synced 2024-11-21 17:05:44 +03:00
PM-10855: Update the minimum SDK to API 29 (Android 10) (#3723)
This commit is contained in:
parent
151b081161
commit
2bed4986a1
9 changed files with 6 additions and 272 deletions
|
@ -11,7 +11,7 @@
|
|||
|
||||
## Compatibility
|
||||
|
||||
- **Minimum SDK**: 28
|
||||
- **Minimum SDK**: 29
|
||||
- **Target SDK**: 34
|
||||
- **Device Types Supported**: Phone and Tablet
|
||||
- **Orientations Supported**: Portrait and Landscape
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.x8bit.bitwarden.data.autofill.builder
|
|||
|
||||
import android.service.autofill.FillRequest
|
||||
import android.service.autofill.SaveInfo
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillAppInfo
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillPartition
|
||||
|
||||
/**
|
||||
|
@ -12,13 +11,11 @@ interface SaveInfoBuilder {
|
|||
/**
|
||||
* Build a save info out the provided data. If that isn't possible, return null.
|
||||
*
|
||||
* @param autofillAppInfo App data that is required for building the [SaveInfo].
|
||||
* @param autofillPartition The portion of the processed [FillRequest] that will be filled.
|
||||
* @param fillRequest The [FillRequest] that initiated the autofill flow.
|
||||
* @param packageName The package name that was extracted from the [FillRequest].
|
||||
*/
|
||||
fun build(
|
||||
autofillAppInfo: AutofillAppInfo,
|
||||
autofillPartition: AutofillPartition,
|
||||
fillRequest: FillRequest,
|
||||
packageName: String?,
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.autofill.builder
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import android.service.autofill.FillRequest
|
||||
import android.service.autofill.SaveInfo
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillAppInfo
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillPartition
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
|
||||
|
@ -16,9 +13,7 @@ class SaveInfoBuilderImpl(
|
|||
val settingsRepository: SettingsRepository,
|
||||
) : SaveInfoBuilder {
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
override fun build(
|
||||
autofillAppInfo: AutofillAppInfo,
|
||||
autofillPartition: AutofillPartition,
|
||||
fillRequest: FillRequest,
|
||||
packageName: String?,
|
||||
|
@ -29,12 +24,8 @@ class SaveInfoBuilderImpl(
|
|||
|
||||
// Docs state that password fields cannot be reliably saved
|
||||
// in Compat mode since they show as masked values.
|
||||
val isInCompatMode = if (autofillAppInfo.sdkInt >= Build.VERSION_CODES.Q) {
|
||||
// Attempt to automatically establish compat request mode on Android 10+
|
||||
(fillRequest.flags or FillRequest.FLAG_COMPATIBILITY_MODE_REQUEST) == fillRequest.flags
|
||||
} else {
|
||||
COMPAT_BROWSERS.contains(packageName)
|
||||
}
|
||||
val isInCompatMode = (fillRequest.flags or
|
||||
FillRequest.FLAG_COMPATIBILITY_MODE_REQUEST) == fillRequest.flags
|
||||
|
||||
// If login and compat mode, the password might be obfuscated,
|
||||
// in which case we should skip the save request.
|
||||
|
@ -58,103 +49,3 @@ class SaveInfoBuilderImpl(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These browsers function using the compatibility shim for the Autofill Framework.
|
||||
*
|
||||
* Ensure that these entries are sorted alphabetically and keep this list synchronized with the
|
||||
* values in /xml/autofill_service_configuration.xml and
|
||||
* /xml-v30/autofill_service_configuration.xml.
|
||||
*/
|
||||
private val COMPAT_BROWSERS: List<String> = listOf(
|
||||
"alook.browser",
|
||||
"alook.browser.google",
|
||||
"app.vanadium.browser",
|
||||
"com.amazon.cloud9",
|
||||
"com.android.browser",
|
||||
"com.android.chrome",
|
||||
"com.android.htmlviewer",
|
||||
"com.avast.android.secure.browser",
|
||||
"com.avg.android.secure.browser",
|
||||
"com.brave.browser",
|
||||
"com.brave.browser_beta",
|
||||
"com.brave.browser_default",
|
||||
"com.brave.browser_dev",
|
||||
"com.brave.browser_nightly",
|
||||
"com.chrome.beta",
|
||||
"com.chrome.canary",
|
||||
"com.chrome.dev",
|
||||
"com.cookiegames.smartcookie",
|
||||
"com.cookiejarapps.android.smartcookieweb",
|
||||
"com.ecosia.android",
|
||||
"com.google.android.apps.chrome",
|
||||
"com.google.android.apps.chrome_dev",
|
||||
"com.google.android.captiveportallogin",
|
||||
"com.iode.firefox",
|
||||
"com.jamal2367.styx",
|
||||
"com.kiwibrowser.browser",
|
||||
"com.kiwibrowser.browser.dev",
|
||||
"com.lemurbrowser.exts",
|
||||
"com.microsoft.emmx",
|
||||
"com.microsoft.emmx.beta",
|
||||
"com.microsoft.emmx.canary",
|
||||
"com.microsoft.emmx.dev",
|
||||
"com.mmbox.browser",
|
||||
"com.mmbox.xbrowser",
|
||||
"com.mycompany.app.soulbrowser",
|
||||
"com.naver.whale",
|
||||
"com.neeva.app",
|
||||
"com.opera.browser",
|
||||
"com.opera.browser.beta",
|
||||
"com.opera.gx",
|
||||
"com.opera.mini.native",
|
||||
"com.opera.mini.native.beta",
|
||||
"com.opera.touch",
|
||||
"com.qflair.browserq",
|
||||
"com.qwant.liberty",
|
||||
"com.rainsee.create",
|
||||
"com.sec.android.app.sbrowser",
|
||||
"com.sec.android.app.sbrowser.beta",
|
||||
"com.stoutner.privacybrowser.free",
|
||||
"com.stoutner.privacybrowser.standard",
|
||||
"com.vivaldi.browser",
|
||||
"com.vivaldi.browser.snapshot",
|
||||
"com.vivaldi.browser.sopranos",
|
||||
"com.yandex.browser",
|
||||
"com.yjllq.internet",
|
||||
"com.yjllq.kito",
|
||||
"com.yujian.ResideMenuDemo",
|
||||
"com.z28j.feel",
|
||||
"idm.internet.download.manager",
|
||||
"idm.internet.download.manager.adm.lite",
|
||||
"idm.internet.download.manager.plus",
|
||||
"io.github.forkmaintainers.iceraven",
|
||||
"mark.via",
|
||||
"mark.via.gp",
|
||||
"net.dezor.browser",
|
||||
"net.slions.fulguris.full.download",
|
||||
"net.slions.fulguris.full.download.debug",
|
||||
"net.slions.fulguris.full.playstore",
|
||||
"net.slions.fulguris.full.playstore.debug",
|
||||
"org.adblockplus.browser",
|
||||
"org.adblockplus.browser.beta",
|
||||
"org.bromite.bromite",
|
||||
"org.bromite.chromium",
|
||||
"org.chromium.chrome",
|
||||
"org.codeaurora.swe.browser",
|
||||
"org.cromite.cromite",
|
||||
"org.gnu.icecat",
|
||||
"org.mozilla.fenix",
|
||||
"org.mozilla.fenix.nightly",
|
||||
"org.mozilla.fennec_aurora",
|
||||
"org.mozilla.fennec_fdroid",
|
||||
"org.mozilla.firefox",
|
||||
"org.mozilla.firefox_beta",
|
||||
"org.mozilla.reference.browser",
|
||||
"org.mozilla.rocket",
|
||||
"org.torproject.torbrowser",
|
||||
"org.torproject.torbrowser_alpha",
|
||||
"org.ungoogled.chromium.extensions.stable",
|
||||
"org.ungoogled.chromium.stable",
|
||||
"us.spotco.fennec_dos",
|
||||
)
|
||||
|
|
|
@ -128,7 +128,6 @@ class AutofillProcessorImpl(
|
|||
autofillRequest = autofillRequest,
|
||||
)
|
||||
val saveInfo = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillRequest.partition,
|
||||
fillRequest = fillRequest,
|
||||
packageName = autofillRequest.packageName,
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
android:supportsInlineSuggestions="true">
|
||||
<!--
|
||||
"Maintain alphabetical order for these compatibility packages and ensure synchronization with
|
||||
both /xml/autofill_service_configuration.xml and the COMPAT_BROWSERS list within
|
||||
SaveInfoBuilderImpl.kt."
|
||||
/xml/autofill_service_configuration.xml.
|
||||
-->
|
||||
<compatibility-package
|
||||
android:name="alook.browser"
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
<autofill-service xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!--
|
||||
"Maintain alphabetical order for these compatibility packages and ensure synchronization with
|
||||
both /xml-v30/autofill_service_configuration.xml and the COMPAT_BROWSERS list within
|
||||
SaveInfoBuilderImpl.kt."
|
||||
/xml-v30/autofill_service_configuration.xml.
|
||||
-->
|
||||
<compatibility-package
|
||||
android:name="alook.browser"
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package com.x8bit.bitwarden.data.autofill.builder
|
||||
|
||||
import android.os.Build
|
||||
import android.service.autofill.FillRequest
|
||||
import android.service.autofill.SaveInfo
|
||||
import android.view.View
|
||||
import android.view.autofill.AutofillId
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillAppInfo
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillPartition
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillView
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
|
@ -26,7 +24,6 @@ class SaveInfoBuilderTest {
|
|||
|
||||
private val settingsRepository: SettingsRepository = mockk()
|
||||
|
||||
private val autofillAppInfo: AutofillAppInfo = mockk()
|
||||
private val fillRequest: FillRequest = mockk()
|
||||
private val autofillIdOptional: AutofillId = mockk()
|
||||
private val autofillViewDataOptional = AutofillView.Data(
|
||||
|
@ -89,7 +86,6 @@ class SaveInfoBuilderTest {
|
|||
|
||||
// Test
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillPartitionCard,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -106,7 +102,6 @@ class SaveInfoBuilderTest {
|
|||
|
||||
// Test
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = AUTOFILL_PARTITION_LOGIN_EMPTY,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -122,11 +117,9 @@ class SaveInfoBuilderTest {
|
|||
// Setup
|
||||
every { settingsRepository.isAutofillSavePromptDisabled } returns false
|
||||
every { fillRequest.flags } returns FillRequest.FLAG_COMPATIBILITY_MODE_REQUEST
|
||||
every { autofillAppInfo.sdkInt } returns Build.VERSION_CODES.TIRAMISU
|
||||
|
||||
// Test
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillPartitionLogin,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -136,35 +129,12 @@ class SaveInfoBuilderTest {
|
|||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `build should return null if autofill possible but package name is in compat list and is login`() {
|
||||
// Setup
|
||||
every { settingsRepository.isAutofillSavePromptDisabled } returns false
|
||||
every { autofillAppInfo.sdkInt } returns Build.VERSION_CODES.P
|
||||
|
||||
// Test
|
||||
COMPAT_BROWSERS
|
||||
.forEach { packageName ->
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillPartitionLogin,
|
||||
fillRequest = fillRequest,
|
||||
packageName = packageName,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertNull(actual)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `build should return SaveInfo with flag set if autofill possible, flags indicate compat mode, and is card`() {
|
||||
// Setup
|
||||
every { settingsRepository.isAutofillSavePromptDisabled } returns false
|
||||
every { fillRequest.flags } returns FillRequest.FLAG_COMPATIBILITY_MODE_REQUEST
|
||||
every { autofillAppInfo.sdkInt } returns Build.VERSION_CODES.TIRAMISU
|
||||
mockBuilder<SaveInfo.Builder> {
|
||||
it.setOptionalIds(arrayOf(autofillIdOptional))
|
||||
}
|
||||
|
@ -174,7 +144,6 @@ class SaveInfoBuilderTest {
|
|||
|
||||
// Test
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillPartitionCard,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -187,126 +156,9 @@ class SaveInfoBuilderTest {
|
|||
anyConstructed<SaveInfo.Builder>().setFlags(SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `build should return SaveInfo if autofill possible, packageName is not in compat list, and is login`() {
|
||||
// Setup
|
||||
every { settingsRepository.isAutofillSavePromptDisabled } returns false
|
||||
every { autofillAppInfo.sdkInt } returns Build.VERSION_CODES.P
|
||||
mockBuilder<SaveInfo.Builder> {
|
||||
it.setOptionalIds(arrayOf(autofillIdOptional))
|
||||
}
|
||||
|
||||
// Test
|
||||
val actual = saveInfoBuilder.build(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
autofillPartition = autofillPartitionLogin,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(saveInfo, actual)
|
||||
verify(exactly = 1) {
|
||||
anyConstructed<SaveInfo.Builder>().setOptionalIds(arrayOf(autofillIdOptional))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val PACKAGE_NAME: String = "com.google"
|
||||
private val AUTOFILL_PARTITION_LOGIN_EMPTY: AutofillPartition.Login = AutofillPartition.Login(
|
||||
views = listOf(),
|
||||
)
|
||||
private val COMPAT_BROWSERS: List<String> = listOf(
|
||||
"alook.browser",
|
||||
"alook.browser.google",
|
||||
"app.vanadium.browser",
|
||||
"com.amazon.cloud9",
|
||||
"com.android.browser",
|
||||
"com.android.chrome",
|
||||
"com.android.htmlviewer",
|
||||
"com.avast.android.secure.browser",
|
||||
"com.avg.android.secure.browser",
|
||||
"com.brave.browser",
|
||||
"com.brave.browser_beta",
|
||||
"com.brave.browser_default",
|
||||
"com.brave.browser_dev",
|
||||
"com.brave.browser_nightly",
|
||||
"com.chrome.beta",
|
||||
"com.chrome.canary",
|
||||
"com.chrome.dev",
|
||||
"com.cookiegames.smartcookie",
|
||||
"com.cookiejarapps.android.smartcookieweb",
|
||||
"com.ecosia.android",
|
||||
"com.google.android.apps.chrome",
|
||||
"com.google.android.apps.chrome_dev",
|
||||
"com.google.android.captiveportallogin",
|
||||
"com.iode.firefox",
|
||||
"com.jamal2367.styx",
|
||||
"com.kiwibrowser.browser",
|
||||
"com.kiwibrowser.browser.dev",
|
||||
"com.lemurbrowser.exts",
|
||||
"com.microsoft.emmx",
|
||||
"com.microsoft.emmx.beta",
|
||||
"com.microsoft.emmx.canary",
|
||||
"com.microsoft.emmx.dev",
|
||||
"com.mmbox.browser",
|
||||
"com.mmbox.xbrowser",
|
||||
"com.mycompany.app.soulbrowser",
|
||||
"com.naver.whale",
|
||||
"com.neeva.app",
|
||||
"com.opera.browser",
|
||||
"com.opera.browser.beta",
|
||||
"com.opera.gx",
|
||||
"com.opera.mini.native",
|
||||
"com.opera.mini.native.beta",
|
||||
"com.opera.touch",
|
||||
"com.qflair.browserq",
|
||||
"com.qwant.liberty",
|
||||
"com.rainsee.create",
|
||||
"com.sec.android.app.sbrowser",
|
||||
"com.sec.android.app.sbrowser.beta",
|
||||
"com.stoutner.privacybrowser.free",
|
||||
"com.stoutner.privacybrowser.standard",
|
||||
"com.vivaldi.browser",
|
||||
"com.vivaldi.browser.snapshot",
|
||||
"com.vivaldi.browser.sopranos",
|
||||
"com.yandex.browser",
|
||||
"com.yjllq.internet",
|
||||
"com.yjllq.kito",
|
||||
"com.yujian.ResideMenuDemo",
|
||||
"com.z28j.feel",
|
||||
"idm.internet.download.manager",
|
||||
"idm.internet.download.manager.adm.lite",
|
||||
"idm.internet.download.manager.plus",
|
||||
"io.github.forkmaintainers.iceraven",
|
||||
"mark.via",
|
||||
"mark.via.gp",
|
||||
"net.dezor.browser",
|
||||
"net.slions.fulguris.full.download",
|
||||
"net.slions.fulguris.full.download.debug",
|
||||
"net.slions.fulguris.full.playstore",
|
||||
"net.slions.fulguris.full.playstore.debug",
|
||||
"org.adblockplus.browser",
|
||||
"org.adblockplus.browser.beta",
|
||||
"org.bromite.bromite",
|
||||
"org.bromite.chromium",
|
||||
"org.chromium.chrome",
|
||||
"org.codeaurora.swe.browser",
|
||||
"org.cromite.cromite",
|
||||
"org.gnu.icecat",
|
||||
"org.mozilla.fenix",
|
||||
"org.mozilla.fenix.nightly",
|
||||
"org.mozilla.fennec_aurora",
|
||||
"org.mozilla.fennec_fdroid",
|
||||
"org.mozilla.firefox",
|
||||
"org.mozilla.firefox_beta",
|
||||
"org.mozilla.reference.browser",
|
||||
"org.mozilla.rocket",
|
||||
"org.torproject.torbrowser",
|
||||
"org.torproject.torbrowser_alpha",
|
||||
"org.ungoogled.chromium.extensions.stable",
|
||||
"org.ungoogled.chromium.stable",
|
||||
"us.spotco.fennec_dos",
|
||||
)
|
||||
|
|
|
@ -157,7 +157,6 @@ class AutofillProcessorTest {
|
|||
} returns autofillRequest
|
||||
every {
|
||||
saveInfoBuilder.build(
|
||||
autofillAppInfo = appInfo,
|
||||
autofillPartition = autofillPartition,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -233,7 +232,6 @@ class AutofillProcessorTest {
|
|||
} returns autofillRequest
|
||||
every {
|
||||
saveInfoBuilder.build(
|
||||
autofillAppInfo = appInfo,
|
||||
autofillPartition = autofillPartition,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
@ -494,7 +492,6 @@ class AutofillProcessorTest {
|
|||
coEvery { filledDataBuilder.build(autofillRequest = autofillRequest) } returns filledData
|
||||
every {
|
||||
saveInfoBuilder.build(
|
||||
autofillAppInfo = appInfo,
|
||||
autofillPartition = autofillPartition,
|
||||
fillRequest = fillRequest,
|
||||
packageName = PACKAGE_NAME,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# SDK Versions
|
||||
compileSdk = "34"
|
||||
targetSdk = "34"
|
||||
minSdk = "28"
|
||||
minSdk = "29"
|
||||
|
||||
# Dependency Versions
|
||||
androidGradlePlugin = "8.5.1"
|
||||
|
|
Loading…
Reference in a new issue