Richard Pospesel pushed to branch android-components-102.0.14-12.5-1 at The Tor Project / Applications / android-components
Commits:
-
52f79946
by Mugurell at 2023-03-16T12:04:07+00:00
-
4ec68dfa
by Mugurell at 2023-03-16T12:04:07+00:00
-
9589ff50
by Mugurell at 2023-03-16T12:04:07+00:00
-
ccafd6d1
by Mugurell at 2023-03-16T12:04:07+00:00
8 changed files:
- components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehavior.kt
- components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/behavior/BrowserToolbarBehaviorTest.kt
- components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadDialogFragment.kt
- components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
- components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ext/DownloadState.kt
- components/feature/downloads/src/main/java/mozilla/components/feature/downloads/ui/DownloaderAppAdapter.kt
- components/feature/prompts/build.gradle
- components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt
Changes:
... | ... | @@ -6,19 +6,15 @@ package mozilla.components.browser.toolbar.behavior |
6 | 6 | |
7 | 7 | import android.content.Context
|
8 | 8 | import android.util.AttributeSet
|
9 | -import android.view.Gravity
|
|
10 | 9 | import android.view.MotionEvent
|
11 | 10 | import android.view.View
|
12 | 11 | import androidx.annotation.VisibleForTesting
|
13 | 12 | import androidx.coordinatorlayout.widget.CoordinatorLayout
|
14 | 13 | import androidx.core.view.ViewCompat
|
15 | -import com.google.android.material.snackbar.Snackbar
|
|
16 | 14 | import mozilla.components.browser.toolbar.BrowserToolbar
|
17 | 15 | import mozilla.components.concept.engine.EngineView
|
18 | 16 | import mozilla.components.support.ktx.android.view.findViewInHierarchy
|
19 | 17 | |
20 | -private const val SMALL_ELEVATION_CHANGE = 0.01f
|
|
21 | - |
|
22 | 18 | /**
|
23 | 19 | * Where the toolbar is placed on the screen.
|
24 | 20 | */
|
... | ... | @@ -35,7 +31,6 @@ enum class ToolbarPosition { |
35 | 31 | *
|
36 | 32 | * This implementation will:
|
37 | 33 | * - Show/Hide the [BrowserToolbar] automatically when scrolling vertically.
|
38 | - * - On showing a [Snackbar] position it above the [BrowserToolbar].
|
|
39 | 34 | * - Snap the [BrowserToolbar] to be hidden or visible when the user stops scrolling.
|
40 | 35 | */
|
41 | 36 | class BrowserToolbarBehavior(
|
... | ... | @@ -128,14 +123,6 @@ class BrowserToolbarBehavior( |
128 | 123 | return false // allow events to be passed to below listeners
|
129 | 124 | }
|
130 | 125 | |
131 | - override fun layoutDependsOn(parent: CoordinatorLayout, child: BrowserToolbar, dependency: View): Boolean {
|
|
132 | - if (toolbarPosition == ToolbarPosition.BOTTOM && dependency is Snackbar.SnackbarLayout) {
|
|
133 | - positionSnackbar(child, dependency)
|
|
134 | - }
|
|
135 | - |
|
136 | - return super.layoutDependsOn(parent, child, dependency)
|
|
137 | - }
|
|
138 | - |
|
139 | 126 | override fun onLayoutChild(
|
140 | 127 | parent: CoordinatorLayout,
|
141 | 128 | child: BrowserToolbar,
|
... | ... | @@ -179,23 +166,6 @@ class BrowserToolbarBehavior( |
179 | 166 | isScrollEnabled = false
|
180 | 167 | }
|
181 | 168 | |
182 | - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
|
183 | - internal fun positionSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) {
|
|
184 | - val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams
|
|
185 | - |
|
186 | - // Position the snackbar above the toolbar so that it doesn't overlay the toolbar.
|
|
187 | - params.anchorId = child.id
|
|
188 | - params.anchorGravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
|
|
189 | - params.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
|
|
190 | - |
|
191 | - snackbarLayout.layoutParams = params
|
|
192 | - |
|
193 | - // In order to avoid the snackbar casting a shadow on the toolbar we adjust the elevation of the snackbar here.
|
|
194 | - // We still place it slightly behind the toolbar so that it will not animate over the toolbar but instead pop
|
|
195 | - // out from under the toolbar.
|
|
196 | - snackbarLayout.elevation = child.elevation - SMALL_ELEVATION_CHANGE
|
|
197 | - }
|
|
198 | - |
|
199 | 169 | @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
200 | 170 | internal fun tryToScrollVertically(distance: Float) {
|
201 | 171 | browserToolbar?.let { toolbar ->
|
... | ... | @@ -6,14 +6,12 @@ package mozilla.components.browser.toolbar.behavior |
6 | 6 | |
7 | 7 | import android.content.Context
|
8 | 8 | import android.graphics.Bitmap
|
9 | -import android.view.Gravity
|
|
10 | 9 | import android.view.MotionEvent.ACTION_DOWN
|
11 | 10 | import android.view.MotionEvent.ACTION_MOVE
|
12 | 11 | import android.widget.FrameLayout
|
13 | 12 | import androidx.coordinatorlayout.widget.CoordinatorLayout
|
14 | 13 | import androidx.core.view.ViewCompat
|
15 | 14 | import androidx.test.ext.junit.runners.AndroidJUnit4
|
16 | -import com.google.android.material.snackbar.Snackbar
|
|
17 | 15 | import mozilla.components.browser.toolbar.BrowserToolbar
|
18 | 16 | import mozilla.components.concept.engine.EngineSession
|
19 | 17 | import mozilla.components.concept.engine.EngineView
|
... | ... | @@ -474,29 +472,6 @@ class BrowserToolbarBehaviorTest { |
474 | 472 | verify(yTranslator).collapseWithAnimation(toolbar)
|
475 | 473 | }
|
476 | 474 | |
477 | - @Test
|
|
478 | - fun `Behavior will position snackbar above toolbar`() {
|
|
479 | - val behavior = BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM)
|
|
480 | - |
|
481 | - val toolbar: BrowserToolbar = mock()
|
|
482 | - doReturn(4223).`when`(toolbar).id
|
|
483 | - |
|
484 | - val layoutParams: CoordinatorLayout.LayoutParams = CoordinatorLayout.LayoutParams(0, 0)
|
|
485 | - |
|
486 | - val snackbarLayout: Snackbar.SnackbarLayout = mock()
|
|
487 | - doReturn(layoutParams).`when`(snackbarLayout).layoutParams
|
|
488 | - |
|
489 | - behavior.layoutDependsOn(
|
|
490 | - parent = mock(),
|
|
491 | - child = toolbar,
|
|
492 | - dependency = snackbarLayout
|
|
493 | - )
|
|
494 | - |
|
495 | - assertEquals(4223, layoutParams.anchorId)
|
|
496 | - assertEquals(Gravity.TOP or Gravity.CENTER_HORIZONTAL, layoutParams.anchorGravity)
|
|
497 | - assertEquals(Gravity.TOP or Gravity.CENTER_HORIZONTAL, layoutParams.gravity)
|
|
498 | - }
|
|
499 | - |
|
500 | 475 | @Test
|
501 | 476 | fun `Behavior will forceExpand when scrolling up and !shouldScroll if the touch was handled in the browser`() {
|
502 | 477 | val behavior = spy(BrowserToolbarBehavior(testContext, null, ToolbarPosition.BOTTOM))
|
... | ... | @@ -10,7 +10,7 @@ import mozilla.components.browser.state.state.content.DownloadState |
10 | 10 | import mozilla.components.feature.downloads.DownloadDialogFragment.Companion.BYTES_TO_MB_LIMIT
|
11 | 11 | import mozilla.components.feature.downloads.DownloadDialogFragment.Companion.KILOBYTE
|
12 | 12 | import mozilla.components.feature.downloads.DownloadDialogFragment.Companion.MEGABYTE
|
13 | -import mozilla.components.support.utils.DownloadUtils
|
|
13 | +import mozilla.components.feature.downloads.ext.realFilenameOrGuessed
|
|
14 | 14 | |
15 | 15 | /**
|
16 | 16 | * This is a general representation of a dialog meant to be used in collaboration with [DownloadsFeature]
|
... | ... | @@ -34,11 +34,7 @@ abstract class DownloadDialogFragment : AppCompatDialogFragment() { |
34 | 34 | */
|
35 | 35 | fun setDownload(download: DownloadState) {
|
36 | 36 | val args = arguments ?: Bundle()
|
37 | - args.putString(
|
|
38 | - KEY_FILE_NAME,
|
|
39 | - download.fileName
|
|
40 | - ?: DownloadUtils.guessFileName(null, download.destinationDirectory, download.url, download.contentType)
|
|
41 | - )
|
|
37 | + args.putString(KEY_FILE_NAME, download.realFilenameOrGuessed)
|
|
42 | 38 | args.putString(KEY_URL, download.url)
|
43 | 39 | args.putLong(KEY_CONTENT_LENGTH, download.contentLength ?: 0)
|
44 | 40 | arguments = args
|
... | ... | @@ -25,6 +25,7 @@ import mozilla.components.browser.state.state.SessionState |
25 | 25 | import mozilla.components.browser.state.state.content.DownloadState
|
26 | 26 | import mozilla.components.browser.state.store.BrowserStore
|
27 | 27 | import mozilla.components.feature.downloads.DownloadDialogFragment.Companion.FRAGMENT_TAG
|
28 | +import mozilla.components.feature.downloads.ext.realFilenameOrGuessed
|
|
28 | 29 | import mozilla.components.feature.downloads.manager.DownloadManager
|
29 | 30 | import mozilla.components.feature.downloads.manager.noop
|
30 | 31 | import mozilla.components.feature.downloads.manager.onDownloadStopped
|
... | ... | @@ -41,6 +42,43 @@ import mozilla.components.support.ktx.kotlin.isSameOriginAs |
41 | 42 | import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
42 | 43 | import mozilla.components.support.utils.Browsers
|
43 | 44 | |
45 | +/**
|
|
46 | + * The name of the file to be downloaded.
|
|
47 | + */
|
|
48 | +@JvmInline
|
|
49 | +value class Filename(val value: String)
|
|
50 | + |
|
51 | +/**
|
|
52 | + * The size of the file to be downloaded expressed as the number of `bytes`.
|
|
53 | + * The value will be `0` if the size is unknown.
|
|
54 | + */
|
|
55 | +@JvmInline
|
|
56 | +value class ContentSize(val value: Long)
|
|
57 | + |
|
58 | +/**
|
|
59 | + * The list of all applications that can perform a download, including this application.
|
|
60 | + */
|
|
61 | +@JvmInline
|
|
62 | +value class ThirdPartyDownloaderApps(val value: List<DownloaderApp>)
|
|
63 | + |
|
64 | +/**
|
|
65 | + * Callback for when the user picked a certain application with which to download the current file.
|
|
66 | + */
|
|
67 | +@JvmInline
|
|
68 | +value class ThirdPartyDownloaderAppChosenCallback(val value: (DownloaderApp) -> Unit)
|
|
69 | + |
|
70 | +/**
|
|
71 | + * Callback for when the positive button of a download dialog was tapped.
|
|
72 | + */
|
|
73 | +@JvmInline
|
|
74 | +value class PositiveActionCallback(val value: () -> Unit)
|
|
75 | + |
|
76 | +/**
|
|
77 | + * Callback for when the negative button of a download dialog was tapped.
|
|
78 | + */
|
|
79 | +@JvmInline
|
|
80 | +value class NegativeActionCallback(val value: () -> Unit)
|
|
81 | + |
|
44 | 82 | /**
|
45 | 83 | * Feature implementation to provide download functionality for the selected
|
46 | 84 | * session. The feature will subscribe to the selected session and listen
|
... | ... | @@ -60,6 +98,10 @@ import mozilla.components.support.utils.Browsers |
60 | 98 | * @property promptsStyling styling properties for the dialog.
|
61 | 99 | * @property shouldForwardToThirdParties Indicates if downloads should be forward to third party apps,
|
62 | 100 | * if there are multiple apps a chooser dialog will shown.
|
101 | + * @property customFirstPartyDownloadDialog An optional delegate for showing a dialog for a download
|
|
102 | + * that will be processed by the current application.
|
|
103 | + * @property customThirdPartyDownloadDialog An optional delegate for showing a dialog for a download
|
|
104 | + * that can be processed by multiple installed applications including the current one.
|
|
63 | 105 | */
|
64 | 106 | @Suppress("LongParameterList", "LargeClass")
|
65 | 107 | class DownloadsFeature(
|
... | ... | @@ -73,7 +115,11 @@ class DownloadsFeature( |
73 | 115 | private val tabId: String? = null,
|
74 | 116 | private val fragmentManager: FragmentManager? = null,
|
75 | 117 | private val promptsStyling: PromptsStyling? = null,
|
76 | - private val shouldForwardToThirdParties: () -> Boolean = { false }
|
|
118 | + private val shouldForwardToThirdParties: () -> Boolean = { false },
|
|
119 | + private val customFirstPartyDownloadDialog:
|
|
120 | + ((Filename, ContentSize, PositiveActionCallback, NegativeActionCallback) -> Unit)? = null,
|
|
121 | + private val customThirdPartyDownloadDialog:
|
|
122 | + ((ThirdPartyDownloaderApps, ThirdPartyDownloaderAppChosenCallback, NegativeActionCallback) -> Unit)? = null,
|
|
77 | 123 | ) : LifecycleAwareFeature, PermissionsFeature {
|
78 | 124 | |
79 | 125 | var onDownloadStopped: onDownloadStopped
|
... | ... | @@ -159,16 +205,45 @@ class DownloadsFeature( |
159 | 205 | val shouldShowAppDownloaderDialog = shouldForwardToThirdParties() && apps.size > 1
|
160 | 206 | |
161 | 207 | return if (shouldShowAppDownloaderDialog) {
|
162 | - showAppDownloaderDialog(tab, download, apps)
|
|
208 | + when (customThirdPartyDownloadDialog) {
|
|
209 | + null -> showAppDownloaderDialog(tab, download, apps)
|
|
210 | + else -> customThirdPartyDownloadDialog.invoke(
|
|
211 | + ThirdPartyDownloaderApps(apps),
|
|
212 | + ThirdPartyDownloaderAppChosenCallback {
|
|
213 | + onDownloaderAppSelected(it, tab, download)
|
|
214 | + },
|
|
215 | + NegativeActionCallback {
|
|
216 | + useCases.cancelDownloadRequest.invoke(tab.id, download.id)
|
|
217 | + },
|
|
218 | + )
|
|
219 | + }
|
|
220 | + |
|
163 | 221 | false
|
164 | 222 | } else {
|
165 | 223 | if (applicationContext.isPermissionGranted(downloadManager.permissions.asIterable())) {
|
166 | - if (fragmentManager != null && !download.skipConfirmation) {
|
|
167 | - showDownloadDialog(tab, download)
|
|
168 | - false
|
|
169 | - } else {
|
|
170 | - useCases.consumeDownload(tab.id, download.id)
|
|
171 | - startDownload(download)
|
|
224 | + when {
|
|
225 | + customFirstPartyDownloadDialog != null && !download.skipConfirmation -> {
|
|
226 | + customFirstPartyDownloadDialog.invoke(
|
|
227 | + Filename(download.realFilenameOrGuessed),
|
|
228 | + ContentSize(download.contentLength ?: 0),
|
|
229 | + PositiveActionCallback {
|
|
230 | + startDownload(download)
|
|
231 | + useCases.consumeDownload.invoke(tab.id, download.id)
|
|
232 | + },
|
|
233 | + NegativeActionCallback {
|
|
234 | + useCases.cancelDownloadRequest.invoke(tab.id, download.id)
|
|
235 | + },
|
|
236 | + )
|
|
237 | + false
|
|
238 | + }
|
|
239 | + fragmentManager != null && !download.skipConfirmation -> {
|
|
240 | + showDownloadDialog(tab, download)
|
|
241 | + false
|
|
242 | + }
|
|
243 | + else -> {
|
|
244 | + useCases.consumeDownload(tab.id, download.id)
|
|
245 | + startDownload(download)
|
|
246 | + }
|
|
172 | 247 | }
|
173 | 248 | } else {
|
174 | 249 | onNeedToRequestPermissions(downloadManager.permissions)
|
... | ... | @@ -264,25 +339,7 @@ class DownloadsFeature( |
264 | 339 | ) {
|
265 | 340 | appChooserDialog.setApps(apps)
|
266 | 341 | appChooserDialog.onAppSelected = { app ->
|
267 | - if (app.packageName == applicationContext.packageName) {
|
|
268 | - if (applicationContext.isPermissionGranted(downloadManager.permissions.asIterable())) {
|
|
269 | - startDownload(download)
|
|
270 | - useCases.consumeDownload(tab.id, download.id)
|
|
271 | - } else {
|
|
272 | - onNeedToRequestPermissions(downloadManager.permissions)
|
|
273 | - }
|
|
274 | - } else {
|
|
275 | - try {
|
|
276 | - applicationContext.startActivity(app.toIntent())
|
|
277 | - } catch (error: ActivityNotFoundException) {
|
|
278 | - val errorMessage = applicationContext.getString(
|
|
279 | - R.string.mozac_feature_downloads_unable_to_open_third_party_app,
|
|
280 | - app.name
|
|
281 | - )
|
|
282 | - Toast.makeText(applicationContext, errorMessage, Toast.LENGTH_SHORT).show()
|
|
283 | - }
|
|
284 | - useCases.consumeDownload(tab.id, download.id)
|
|
285 | - }
|
|
342 | + onDownloaderAppSelected(app, tab, download)
|
|
286 | 343 | }
|
287 | 344 | |
288 | 345 | appChooserDialog.onDismiss = {
|
... | ... | @@ -294,6 +351,29 @@ class DownloadsFeature( |
294 | 351 | }
|
295 | 352 | }
|
296 | 353 | |
354 | + @VisibleForTesting
|
|
355 | + internal fun onDownloaderAppSelected(app: DownloaderApp, tab: SessionState, download: DownloadState) {
|
|
356 | + if (app.packageName == applicationContext.packageName) {
|
|
357 | + if (applicationContext.isPermissionGranted(downloadManager.permissions.asIterable())) {
|
|
358 | + startDownload(download)
|
|
359 | + useCases.consumeDownload(tab.id, download.id)
|
|
360 | + } else {
|
|
361 | + onNeedToRequestPermissions(downloadManager.permissions)
|
|
362 | + }
|
|
363 | + } else {
|
|
364 | + try {
|
|
365 | + applicationContext.startActivity(app.toIntent())
|
|
366 | + } catch (error: ActivityNotFoundException) {
|
|
367 | + val errorMessage = applicationContext.getString(
|
|
368 | + R.string.mozac_feature_downloads_unable_to_open_third_party_app,
|
|
369 | + app.name,
|
|
370 | + )
|
|
371 | + Toast.makeText(applicationContext, errorMessage, Toast.LENGTH_SHORT).show()
|
|
372 | + }
|
|
373 | + useCases.consumeDownload(tab.id, download.id)
|
|
374 | + }
|
|
375 | + }
|
|
376 | + |
|
297 | 377 | private fun getAppDownloaderDialog() = findPreviousAppDownloaderDialogFragment()
|
298 | 378 | ?: DownloadAppChooserDialog.newInstance(
|
299 | 379 | promptsStyling?.gravity,
|
... | ... | @@ -47,3 +47,6 @@ internal fun DownloadState.withResponse(headers: Headers, stream: InputStream?): |
47 | 47 | contentLength = contentLength ?: headers[CONTENT_LENGTH]?.toLongOrNull()
|
48 | 48 | )
|
49 | 49 | }
|
50 | + |
|
51 | +internal val DownloadState.realFilenameOrGuessed
|
|
52 | + get() = fileName ?: DownloadUtils.guessFileName(null, destinationDirectory, url, contentType) |
... | ... | @@ -16,10 +16,10 @@ import mozilla.components.feature.downloads.R |
16 | 16 | /**
|
17 | 17 | * An adapter for displaying the applications that can perform downloads.
|
18 | 18 | */
|
19 | -internal class DownloaderAppAdapter(
|
|
19 | +class DownloaderAppAdapter(
|
|
20 | 20 | context: Context,
|
21 | 21 | private val apps: List<DownloaderApp>,
|
22 | - val onAppSelected: ((DownloaderApp) -> Unit)
|
|
22 | + val onAppSelected: ((DownloaderApp) -> Unit),
|
|
23 | 23 | ) : RecyclerView.Adapter<DownloaderAppViewHolder>() {
|
24 | 24 | |
25 | 25 | private val inflater = LayoutInflater.from(context)
|
... | ... | @@ -49,11 +49,14 @@ internal class DownloaderAppAdapter( |
49 | 49 | /**
|
50 | 50 | * View holder for a [DownloaderApp] item.
|
51 | 51 | */
|
52 | -internal class DownloaderAppViewHolder(
|
|
52 | +class DownloaderAppViewHolder(
|
|
53 | 53 | itemView: View,
|
54 | 54 | val nameLabel: TextView,
|
55 | - val iconImage: ImageView
|
|
55 | + val iconImage: ImageView,
|
|
56 | 56 | ) : RecyclerView.ViewHolder(itemView) {
|
57 | + /**
|
|
58 | + * Show a certain downloader application in the current View.
|
|
59 | + */
|
|
57 | 60 | fun bind(app: DownloaderApp, onAppSelected: ((DownloaderApp) -> Unit)) {
|
58 | 61 | itemView.app = app
|
59 | 62 | itemView.setOnClickListener {
|
... | ... | @@ -31,6 +31,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { |
31 | 31 | dependencies {
|
32 | 32 | implementation project(':browser-state')
|
33 | 33 | implementation project(':concept-engine')
|
34 | + implementation project(':feature-session')
|
|
34 | 35 | implementation project(':lib-state')
|
35 | 36 | implementation project(':support-ktx')
|
36 | 37 | implementation project(':support-utils')
|
... | ... | @@ -46,6 +47,7 @@ dependencies { |
46 | 47 | testImplementation Dependencies.testing_coroutines
|
47 | 48 | testImplementation Dependencies.testing_robolectric
|
48 | 49 | testImplementation Dependencies.testing_mockito
|
50 | + testImplementation project(':feature-session')
|
|
49 | 51 | testImplementation project(':support-test')
|
50 | 52 | testImplementation project(':support-test-libstate')
|
51 | 53 |
... | ... | @@ -71,6 +71,8 @@ import mozilla.components.feature.prompts.login.LoginExceptions |
71 | 71 | import mozilla.components.feature.prompts.login.LoginPicker
|
72 | 72 | import mozilla.components.feature.prompts.share.DefaultShareDelegate
|
73 | 73 | import mozilla.components.feature.prompts.share.ShareDelegate
|
74 | +import mozilla.components.feature.session.SessionUseCases
|
|
75 | +import mozilla.components.feature.session.SessionUseCases.ExitFullScreenUseCase
|
|
74 | 76 | import mozilla.components.lib.state.ext.flowScoped
|
75 | 77 | import mozilla.components.support.base.feature.ActivityResultHandler
|
76 | 78 | import mozilla.components.support.base.feature.LifecycleAwareFeature
|
... | ... | @@ -111,6 +113,7 @@ internal const val FRAGMENT_TAG = "mozac_feature_prompt_dialog" |
111 | 113 | * @property fragmentManager The [FragmentManager] to be used when displaying
|
112 | 114 | * a dialog (fragment).
|
113 | 115 | * @property shareDelegate Delegate used to display share sheet.
|
116 | + * @property exitFullscreenUsecase Usecase allowing to exit browser tabs' fullscreen mode.
|
|
114 | 117 | * @property loginStorageDelegate Delegate used to access login storage. If null,
|
115 | 118 | * 'save login'prompts will not be shown.
|
116 | 119 | * @property isSaveLoginEnabled A callback invoked when a login prompt is triggered. If false,
|
... | ... | @@ -144,6 +147,7 @@ class PromptFeature private constructor( |
144 | 147 | private var customTabId: String?,
|
145 | 148 | private val fragmentManager: FragmentManager,
|
146 | 149 | private val shareDelegate: ShareDelegate,
|
150 | + private val exitFullscreenUsecase: ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
|
|
147 | 151 | override val creditCardValidationDelegate: CreditCardValidationDelegate? = null,
|
148 | 152 | override val loginValidationDelegate: LoginValidationDelegate? = null,
|
149 | 153 | private val isSaveLoginEnabled: () -> Boolean = { false },
|
... | ... | @@ -184,6 +188,7 @@ class PromptFeature private constructor( |
184 | 188 | customTabId: String? = null,
|
185 | 189 | fragmentManager: FragmentManager,
|
186 | 190 | shareDelegate: ShareDelegate = DefaultShareDelegate(),
|
191 | + exitFullscreenUsecase: ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
|
|
187 | 192 | creditCardValidationDelegate: CreditCardValidationDelegate? = null,
|
188 | 193 | loginValidationDelegate: LoginValidationDelegate? = null,
|
189 | 194 | isSaveLoginEnabled: () -> Boolean = { false },
|
... | ... | @@ -202,6 +207,7 @@ class PromptFeature private constructor( |
202 | 207 | customTabId = customTabId,
|
203 | 208 | fragmentManager = fragmentManager,
|
204 | 209 | shareDelegate = shareDelegate,
|
210 | + exitFullscreenUsecase = exitFullscreenUsecase,
|
|
205 | 211 | creditCardValidationDelegate = creditCardValidationDelegate,
|
206 | 212 | loginValidationDelegate = loginValidationDelegate,
|
207 | 213 | isSaveLoginEnabled = isSaveLoginEnabled,
|
... | ... | @@ -222,6 +228,7 @@ class PromptFeature private constructor( |
222 | 228 | customTabId: String? = null,
|
223 | 229 | fragmentManager: FragmentManager,
|
224 | 230 | shareDelegate: ShareDelegate = DefaultShareDelegate(),
|
231 | + exitFullscreenUsecase: ExitFullScreenUseCase = SessionUseCases(store).exitFullscreen,
|
|
225 | 232 | creditCardValidationDelegate: CreditCardValidationDelegate? = null,
|
226 | 233 | loginValidationDelegate: LoginValidationDelegate? = null,
|
227 | 234 | isSaveLoginEnabled: () -> Boolean = { false },
|
... | ... | @@ -240,6 +247,7 @@ class PromptFeature private constructor( |
240 | 247 | customTabId = customTabId,
|
241 | 248 | fragmentManager = fragmentManager,
|
242 | 249 | shareDelegate = shareDelegate,
|
250 | + exitFullscreenUsecase = exitFullscreenUsecase,
|
|
243 | 251 | creditCardValidationDelegate = creditCardValidationDelegate,
|
244 | 252 | loginValidationDelegate = loginValidationDelegate,
|
245 | 253 | isSaveLoginEnabled = isSaveLoginEnabled,
|
... | ... | @@ -420,6 +428,10 @@ class PromptFeature private constructor( |
420 | 428 | internal fun onPromptRequested(session: SessionState) {
|
421 | 429 | // Some requests are handle with intents
|
422 | 430 | session.content.promptRequests.lastOrNull()?.let { promptRequest ->
|
431 | + store.state.findTabOrCustomTabOrSelectedTab(customTabId)?.let {
|
|
432 | + exitFullscreenUsecase(it.id)
|
|
433 | + }
|
|
434 | + |
|
423 | 435 | when (promptRequest) {
|
424 | 436 | is File -> filePicker.handleFileRequest(promptRequest)
|
425 | 437 | is Share -> handleShareRequest(promptRequest, session)
|