зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d29ebe7bac
Коммит
93e2b679ea
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче