Skip to content

Commit ad7bf74

Browse files
Mugurellplingurar@mozilla.com
authored andcommitted
Bug 1991654 - part 2 - Use a generic EngineViewScrollingBehavior r=android-reviewers,Roger
This will allow to easily switch between the current way of scrolling the dynamic toolbar and the new one based on APZ scrolling data. Differential Revision: https://phabricator.services.mozilla.com/D267222
1 parent 06b4ab5 commit ad7bf74

File tree

17 files changed

+328
-290
lines changed

17 files changed

+328
-290
lines changed

mobile/android/android-components/components/browser/toolbar/src/main/java/mozilla/components/browser/toolbar/BrowserToolbar.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import mozilla.components.support.ktx.kotlin.trimmed
3737
import mozilla.components.ui.autocomplete.AutocompleteView
3838
import mozilla.components.ui.autocomplete.InlineAutocompleteEditText
3939
import mozilla.components.ui.autocomplete.OnFilterListener
40-
import mozilla.components.ui.widgets.behavior.EngineViewScrollingGesturesBehavior
40+
import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior
4141
import kotlin.coroutines.CoroutineContext
4242

4343
internal fun ImageView.setTintResource(@ColorRes tintColorResource: Int) {
@@ -394,26 +394,26 @@ class BrowserToolbar @JvmOverloads constructor(
394394
override fun enableScrolling() {
395395
// Behavior can be changed without us knowing. Not safe to use a memoized value.
396396
(layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
397-
(behavior as? EngineViewScrollingGesturesBehavior)?.enableScrolling()
397+
(behavior as? EngineViewScrollingBehavior)?.enableScrolling()
398398
}
399399
}
400400

401401
override fun disableScrolling() {
402402
// Behavior can be changed without us knowing. Not safe to use a memoized value.
403403
(layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
404-
(behavior as? EngineViewScrollingGesturesBehavior)?.disableScrolling()
404+
(behavior as? EngineViewScrollingBehavior)?.disableScrolling()
405405
}
406406
}
407407

408408
override fun expand() {
409409
(layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
410-
(behavior as? EngineViewScrollingGesturesBehavior)?.forceExpand(this@BrowserToolbar)
410+
(behavior as? EngineViewScrollingBehavior)?.forceExpand()
411411
}
412412
}
413413

414414
override fun collapse() {
415415
(layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
416-
(behavior as? EngineViewScrollingGesturesBehavior)?.forceCollapse(this@BrowserToolbar)
416+
(behavior as? EngineViewScrollingBehavior)?.forceCollapse()
417417
}
418418
}
419419

mobile/android/android-components/components/browser/toolbar/src/test/java/mozilla/components/browser/toolbar/BrowserToolbarTest.kt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import mozilla.components.browser.toolbar.display.DisplayToolbar
2020
import mozilla.components.browser.toolbar.display.DisplayToolbarViews
2121
import mozilla.components.browser.toolbar.display.MenuButton
2222
import mozilla.components.browser.toolbar.edit.EditToolbar
23+
import mozilla.components.concept.engine.EngineView
2324
import mozilla.components.concept.toolbar.AutocompleteDelegate
2425
import mozilla.components.concept.toolbar.Toolbar
2526
import mozilla.components.concept.toolbar.Toolbar.SiteInfo
@@ -29,8 +30,8 @@ import mozilla.components.support.test.argumentCaptor
2930
import mozilla.components.support.test.mock
3031
import mozilla.components.support.test.robolectric.testContext
3132
import mozilla.components.support.test.whenever
33+
import mozilla.components.ui.widgets.behavior.DependencyGravity.Bottom
3234
import mozilla.components.ui.widgets.behavior.EngineViewScrollingGesturesBehavior
33-
import mozilla.components.ui.widgets.behavior.ViewPosition
3435
import org.junit.Assert.assertEquals
3536
import org.junit.Assert.assertFalse
3637
import org.junit.Assert.assertNotEquals
@@ -42,6 +43,7 @@ import org.junit.runner.RunWith
4243
import org.mockito.ArgumentCaptor
4344
import org.mockito.ArgumentMatchers
4445
import org.mockito.Mockito.any
46+
import org.mockito.Mockito.doReturn
4547
import org.mockito.Mockito.mock
4648
import org.mockito.Mockito.never
4749
import org.mockito.Mockito.spy
@@ -924,7 +926,9 @@ class BrowserToolbarTest {
924926
fun `enable scrolling is forwarded to the toolbar behavior`() {
925927
// Seems like real instances are needed for things to be set properly
926928
val toolbar = BrowserToolbar(testContext)
927-
val behavior = spy(EngineViewScrollingGesturesBehavior(testContext, null, ViewPosition.BOTTOM))
929+
val engineView: EngineView = mock()
930+
doReturn(View(testContext)).`when`(engineView).asView()
931+
val behavior = spy(EngineViewScrollingGesturesBehavior(engineView, toolbar, Bottom))
928932
val params = CoordinatorLayout.LayoutParams(10, 10).apply {
929933
this.behavior = behavior
930934
}
@@ -939,7 +943,9 @@ class BrowserToolbarTest {
939943
fun `disable scrolling is forwarded to the toolbar behavior`() {
940944
// Seems like real instances are needed for things to be set properly
941945
val toolbar = BrowserToolbar(testContext)
942-
val behavior = spy(EngineViewScrollingGesturesBehavior(testContext, null, ViewPosition.BOTTOM))
946+
val engineView: EngineView = mock()
947+
doReturn(View(testContext)).`when`(engineView).asView()
948+
val behavior = spy(EngineViewScrollingGesturesBehavior(engineView, toolbar, Bottom))
943949
val params = CoordinatorLayout.LayoutParams(10, 10).apply {
944950
this.behavior = behavior
945951
}
@@ -954,30 +960,34 @@ class BrowserToolbarTest {
954960
fun `expand is forwarded to the toolbar behavior`() {
955961
// Seems like real instances are needed for things to be set properly
956962
val toolbar = BrowserToolbar(testContext)
957-
val behavior = spy(EngineViewScrollingGesturesBehavior(testContext, null, ViewPosition.BOTTOM))
963+
val engineView: EngineView = mock()
964+
doReturn(View(testContext)).`when`(engineView).asView()
965+
val behavior = spy(EngineViewScrollingGesturesBehavior(engineView, toolbar, Bottom))
958966
val params = CoordinatorLayout.LayoutParams(10, 10).apply {
959967
this.behavior = behavior
960968
}
961969
toolbar.layoutParams = params
962970

963971
toolbar.expand()
964972

965-
verify(behavior).forceExpand(toolbar)
973+
verify(behavior).forceExpand()
966974
}
967975

968976
@Test
969977
fun `collapse is forwarded to the toolbar behavior`() {
970978
// Seems like real instances are needed for things to be set properly
971979
val toolbar = BrowserToolbar(testContext)
972-
val behavior = spy(EngineViewScrollingGesturesBehavior(testContext, null, ViewPosition.BOTTOM))
980+
val engineView: EngineView = mock()
981+
doReturn(View(testContext)).`when`(engineView).asView()
982+
val behavior = spy(EngineViewScrollingGesturesBehavior(engineView, toolbar, Bottom))
973983
val params = CoordinatorLayout.LayoutParams(10, 10).apply {
974984
this.behavior = behavior
975985
}
976986
toolbar.layoutParams = params
977987

978988
toolbar.collapse()
979989

980-
verify(behavior).forceCollapse(toolbar)
990+
verify(behavior).forceCollapse()
981991
}
982992

983993
@Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package mozilla.components.ui.widgets.behavior
6+
7+
/**
8+
* Where the dynamic view dependent on webpage scrolls is placed on the screen.
9+
*/
10+
sealed interface DependencyGravity {
11+
/**
12+
* The view is placed at the top of the screen.
13+
*/
14+
data object Top : DependencyGravity
15+
16+
/**
17+
* The view is placed at the bottom of the screen.
18+
*/
19+
data object Bottom : DependencyGravity
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package mozilla.components.ui.widgets.behavior
6+
7+
import android.view.View
8+
import androidx.annotation.VisibleForTesting
9+
import androidx.coordinatorlayout.widget.CoordinatorLayout
10+
import mozilla.components.concept.engine.EngineView
11+
12+
/**
13+
* [CoordinatorLayout.Behavior] that will synchronize scrolling between [engineView] and [dependency].
14+
*
15+
* @param engineView [EngineView] to synchronize scrolling with.
16+
* @param dependency [View] that will be scrolled to match [engineView].
17+
* @param dependencyGravity whether [dependency] is placed on the top or bottom of the screen.
18+
*/
19+
abstract class EngineViewScrollingBehavior(
20+
engineView: EngineView,
21+
private val dependency: View,
22+
dependencyGravity: DependencyGravity,
23+
) : CoordinatorLayout.Behavior<View>(engineView.asView().context, null) {
24+
var isScrollEnabled = false
25+
@VisibleForTesting set
26+
27+
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
28+
internal var yTranslator = ViewYTranslator(dependencyGravity)
29+
30+
/**
31+
* Used to expand the dependent View.
32+
*/
33+
fun forceExpand() {
34+
yTranslator.expandWithAnimation(dependency)
35+
}
36+
37+
/**
38+
* Used to collapse the dependent View.
39+
*/
40+
fun forceCollapse() {
41+
yTranslator.collapseWithAnimation(dependency)
42+
}
43+
44+
/**
45+
* Allow this view to be animated.
46+
*
47+
* @see disableScrolling
48+
*/
49+
fun enableScrolling() {
50+
isScrollEnabled = true
51+
}
52+
53+
/**
54+
* Disable scrolling of the view irrespective of the intrinsic checks.
55+
*
56+
* @see enableScrolling
57+
*/
58+
fun disableScrolling() {
59+
isScrollEnabled = false
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
package mozilla.components.ui.widgets.behavior
6+
7+
import android.view.View
8+
import mozilla.components.concept.base.crash.CrashReporting
9+
import mozilla.components.concept.engine.EngineView
10+
11+
/**
12+
* Factory for [EngineViewScrollingBehavior] instances.
13+
*/
14+
object EngineViewScrollingBehaviorFactory {
15+
/**
16+
* Create a new [EngineViewScrollingBehavior] instance.
17+
*
18+
* @param engineView [EngineView] to synchronize scrolling with.
19+
* @param dependency [View] that will be scrolled to match [engineView].
20+
* @param dependencyGravity whether [dependency] is placed on the top or bottom of the screen.
21+
* @param crashReporting [CrashReporting] to use for reporting crashes.
22+
*/
23+
fun build(
24+
engineView: EngineView,
25+
dependency: View,
26+
dependencyGravity: DependencyGravity,
27+
crashReporting: CrashReporting? = null,
28+
) = EngineViewScrollingGesturesBehavior(
29+
engineView = engineView,
30+
dependency = dependency,
31+
dependencyGravity = dependencyGravity,
32+
crashReporting = crashReporting,
33+
)
34+
}

0 commit comments

Comments
 (0)