Bug 1907922 - Redirect to external app without prompt when authenticating r=android-reviewers,avirvara

Differential Revision: https://phabricator.services.mozilla.com/D220310
This commit is contained in:
Roger Yang 2024-09-09 15:34:13 +00:00
Родитель d29ebe7bac
Коммит 93e2b679ea
2 изменённых файлов: 95 добавлений и 13 удалений

Просмотреть файл

@ -108,7 +108,7 @@ class AppLinksFeature(
}
@Suppress("ComplexCondition")
if (isSameCallerAndApp(tab, appIntent) || (!tab.content.private && !shouldPrompt()) ||
if (isAuthentication(tab, appIntent) || (!tab.content.private && !shouldPrompt()) ||
fragmentManager == null
) {
doOpenApp()
@ -172,13 +172,24 @@ class AppLinksFeature(
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun isSameCallerAndApp(tab: SessionState, appIntent: Intent): Boolean {
return (tab.source as? SessionState.Source.External.CustomTab)?.let { externalSource ->
when (externalSource.caller?.packageId) {
null -> false
appIntent.component?.packageName -> true
else -> false
internal fun isAuthentication(tab: SessionState, appIntent: Intent): Boolean {
return when (tab.source) {
is SessionState.Source.External.ActionSend,
is SessionState.Source.External.ActionSearch,
-> false
// CustomTab and ActionView can be used for authentication
is SessionState.Source.External.CustomTab,
is SessionState.Source.External.ActionView,
-> {
(tab.source as? SessionState.Source.External)?.let { externalSource ->
when (externalSource.caller?.packageId) {
null -> false
appIntent.component?.packageName -> true
else -> false
}
} ?: false
}
} ?: false
else -> false
}
}
}

Просмотреть файл

@ -223,7 +223,7 @@ class AppLinksFeatureTest {
}
@Test
fun `WHEN non-custom tab and caller is the same as external app THEN an external app dialog is shown`() {
fun `WHEN tab have action view and caller is the same as external app THEN an external app dialog is shown`() {
feature = spy(
AppLinksFeature(
context = mockContext,
@ -254,6 +254,77 @@ class AppLinksFeatureTest {
feature.handleAppIntent(tab, intentUrl, appIntent)
verify(mockDialog, never()).showNow(eq(mockFragmentManager), anyString())
}
@Test
fun `WHEN tab have action send and caller is the same as external app THEN an external app dialog is shown`() {
feature = spy(
AppLinksFeature(
context = mockContext,
store = store,
fragmentManager = mockFragmentManager,
useCases = mockUseCases,
dialog = mockDialog,
loadUrlUseCase = mockLoadUrlUseCase,
shouldPrompt = { true },
),
).also {
it.start()
}
val tab =
createCustomTab(
id = "d",
url = webUrl,
source = SessionState.Source.External.ActionSend(
ExternalPackage("com.zxing.app", PackageCategory.PRODUCTIVITY),
),
)
val appIntent: Intent = mock()
val componentName: ComponentName = mock()
doReturn(componentName).`when`(appIntent).component
doReturn("com.zxing.app").`when`(componentName).packageName
feature.handleAppIntent(tab, intentUrl, appIntent)
verify(mockDialog).showNow(eq(mockFragmentManager), anyString())
verify(mockOpenRedirect, never()).invoke(any(), anyBoolean(), any())
}
@Test
fun `WHEN tab have action search and caller is the same as external app THEN an external app dialog is shown`() {
feature = spy(
AppLinksFeature(
context = mockContext,
store = store,
fragmentManager = mockFragmentManager,
useCases = mockUseCases,
dialog = mockDialog,
loadUrlUseCase = mockLoadUrlUseCase,
shouldPrompt = { true },
),
).also {
it.start()
}
val tab =
createCustomTab(
id = "d",
url = webUrl,
source = SessionState.Source.External.ActionSearch(
ExternalPackage("com.zxing.app", PackageCategory.PRODUCTIVITY),
),
)
val appIntent: Intent = mock()
val componentName: ComponentName = mock()
doReturn(componentName).`when`(appIntent).component
doReturn("com.zxing.app").`when`(componentName).packageName
feature.handleAppIntent(tab, intentUrl, appIntent)
verify(mockDialog).showNow(eq(mockFragmentManager), anyString())
verify(mockOpenRedirect, never()).invoke(any(), anyBoolean(), any())
}
@ -345,10 +416,10 @@ class AppLinksFeatureTest {
val componentName: ComponentName = mock()
doReturn(componentName).`when`(appIntent).component
doReturn("com.zxing.app").`when`(componentName).packageName
assertTrue(feature.isSameCallerAndApp(customTab, appIntent))
assertTrue(feature.isAuthentication(customTab, appIntent))
val tab = createTab(webUrl, private = true)
assertFalse(feature.isSameCallerAndApp(tab, appIntent))
assertFalse(feature.isAuthentication(tab, appIntent))
val customTab2 =
createCustomTab(
@ -358,9 +429,9 @@ class AppLinksFeatureTest {
ExternalPackage("com.example.app", PackageCategory.PRODUCTIVITY),
),
)
assertFalse(feature.isSameCallerAndApp(customTab2, appIntent))
assertFalse(feature.isAuthentication(customTab2, appIntent))
doReturn(null).`when`(componentName).packageName
assertFalse(feature.isSameCallerAndApp(customTab, appIntent))
assertFalse(feature.isAuthentication(customTab, appIntent))
}
}