Commit ffba4ecc authored by Tiger Oakes's avatar Tiger Oakes
Browse files

Change WebAppHideToolbarFeature to use callback

parent eef0c4bd
......@@ -4,9 +4,7 @@
package mozilla.components.feature.pwa.feature
import android.view.View
import androidx.core.net.toUri
import androidx.core.view.isVisible
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
......@@ -41,19 +39,19 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
* In standard custom tabs, no scopes are trusted.
* As a result the URL has no impact on toolbar visibility.
*
* @param toolbar Toolbar to show or hide.
* @param store Reference to the browser store where tab state is located.
* @param customTabsStore Reference to the store that communicates with the custom tabs service.
* @param tabId ID of the tab session, or null if the selected session should be used.
* @param manifest Reference to the cached [WebAppManifest] for the current PWA.
* Null if this feature is not used in a PWA context.
* @param setToolbarVisibility Callback to show or hide the toolbar.
*/
class WebAppHideToolbarFeature(
private val toolbar: View,
private val store: BrowserStore,
private val customTabsStore: CustomTabsServiceStore,
private val tabId: String? = null,
manifest: WebAppManifest? = null
manifest: WebAppManifest? = null,
private val setToolbarVisibility: (Boolean) -> Unit
) : LifecycleAwareFeature {
private val manifestScope = listOfNotNull(manifest?.getTrustedScope())
......@@ -63,7 +61,7 @@ class WebAppHideToolbarFeature(
// Hide the toolbar by default to prevent a flash.
val tab = store.state.findTabOrCustomTabOrSelectedTab(tabId)
val customTabState = customTabsStore.state.getCustomTabStateForTab(tab)
toolbar.isVisible = shouldToolbarBeVisible(tab, customTabState)
setToolbarVisibility(shouldToolbarBeVisible(tab, customTabState))
}
@ExperimentalCoroutinesApi
......@@ -84,7 +82,7 @@ class WebAppHideToolbarFeature(
.map { (tab, customTabState) -> shouldToolbarBeVisible(tab, customTabState) }
.ifChanged()
.collect { toolbarVisible ->
toolbar.isVisible = toolbarVisible
setToolbarVisibility(toolbarVisible)
}
}
}
......
......@@ -4,7 +4,6 @@
package mozilla.components.feature.pwa.feature
import android.view.View
import androidx.browser.customtabs.CustomTabsService.RELATION_HANDLE_ALL_URLS
import androidx.browser.customtabs.CustomTabsSessionToken
import androidx.core.net.toUri
......@@ -29,9 +28,10 @@ import mozilla.components.feature.customtabs.store.ValidateRelationshipAction
import mozilla.components.feature.customtabs.store.VerificationStatus
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
......@@ -42,11 +42,16 @@ class WebAppHideToolbarFeatureTest {
private val customTabId = "custom-id"
private val testDispatcher = TestCoroutineDispatcher()
private val toolbar = View(testContext)
private var toolbarVisible = false
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)
@Before
fun setup() {
toolbarVisible = false
}
@Test
fun `hides toolbar immediately based on PWA manifest`() {
val tab = CustomTabSessionState(
......@@ -57,14 +62,15 @@ class WebAppHideToolbarFeatureTest {
val store = BrowserStore(BrowserState(customTabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
CustomTabsServiceStore(),
tabId = tab.id,
manifest = mockManifest("https://mozilla.org")
)
) {
toolbarVisible = it
}
feature.start()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -81,13 +87,14 @@ class WebAppHideToolbarFeatureTest {
))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
customTabsStore,
tabId = tab.id
)
) {
toolbarVisible = it
}
feature.start()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -95,18 +102,22 @@ class WebAppHideToolbarFeatureTest {
val tab = createTab("https://mozilla.org")
val store = BrowserStore(BrowserState(tabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(toolbar, store, CustomTabsServiceStore(), tabId = tab.id)
val feature = WebAppHideToolbarFeature(store, CustomTabsServiceStore(), tabId = tab.id) {
toolbarVisible = it
}
feature.start()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
}
@Test
fun `does not hide toolbar for an invalid tab`() {
val store = BrowserStore()
val feature = WebAppHideToolbarFeature(toolbar, store, CustomTabsServiceStore())
val feature = WebAppHideToolbarFeature(store, CustomTabsServiceStore()) {
toolbarVisible = it
}
feature.start()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
}
@Test
......@@ -119,9 +130,11 @@ class WebAppHideToolbarFeatureTest {
)
val store = BrowserStore(BrowserState(tabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(toolbar, store, CustomTabsServiceStore(), tabId = tab.id)
val feature = WebAppHideToolbarFeature(store, CustomTabsServiceStore(), tabId = tab.id) {
toolbarVisible = it
}
feature.start()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -134,9 +147,11 @@ class WebAppHideToolbarFeatureTest {
)
val store = BrowserStore(BrowserState(tabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(toolbar, store, CustomTabsServiceStore(), tabId = tab.id)
val feature = WebAppHideToolbarFeature(store, CustomTabsServiceStore(), tabId = tab.id) {
toolbarVisible = it
}
feature.start()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -153,13 +168,14 @@ class WebAppHideToolbarFeatureTest {
))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
customTabsStore,
tabId = tab.id
)
) {
toolbarVisible = it
}
feature.start()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
}
@Test
......@@ -175,32 +191,33 @@ class WebAppHideToolbarFeatureTest {
tabs = mapOf(token to mockCustomTabState("https://mozilla.com", "https://m.mozilla.com"))
))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
customTabsStore,
tabId = customTabId
)
) {
toolbarVisible = it
}
feature.start()
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.com/example-page")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://firefox.com/out-of-scope")
).joinBlocking()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.com/back-in-scope")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://m.mozilla.com/second-origin")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -208,33 +225,34 @@ class WebAppHideToolbarFeatureTest {
val tab = createCustomTab(id = customTabId, url = "https://mozilla.org")
val store = BrowserStore(BrowserState(customTabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
CustomTabsServiceStore(),
tabId = customTabId,
manifest = mockManifest("https://mozilla.github.io/my-app/")
)
) {
toolbarVisible = it
}
feature.start()
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.github.io/my-app/")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://firefox.com/out-of-scope")
).joinBlocking()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.github.io/my-app-almost-in-scope")
).joinBlocking()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.github.io/my-app/sub-page")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -242,23 +260,24 @@ class WebAppHideToolbarFeatureTest {
val tab = createCustomTab(id = customTabId, url = "https://mozilla.org")
val store = BrowserStore(BrowserState(customTabs = listOf(tab)))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
CustomTabsServiceStore(),
tabId = customTabId,
manifest = mockManifest("https://mozilla.github.io/prefix")
)
) {
toolbarVisible = it
}
feature.start()
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.github.io/prefix/")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
store.dispatch(
ContentAction.UpdateUrlAction(customTabId, "https://mozilla.github.io/prefix-of/resource.html")
).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
@Test
......@@ -274,11 +293,12 @@ class WebAppHideToolbarFeatureTest {
tabs = mapOf(token to mockCustomTabState())
))
val feature = WebAppHideToolbarFeature(
toolbar,
store,
customTabsStore,
tabId = customTabId
)
) {
toolbarVisible = it
}
feature.start()
customTabsStore.dispatch(ValidateRelationshipAction(
......@@ -287,7 +307,7 @@ class WebAppHideToolbarFeatureTest {
"https://m.mozilla.com".toUri(),
VerificationStatus.PENDING
)).joinBlocking()
assertEquals(View.VISIBLE, toolbar.visibility)
assertTrue(toolbarVisible)
customTabsStore.dispatch(ValidateRelationshipAction(
token,
......@@ -295,7 +315,7 @@ class WebAppHideToolbarFeatureTest {
"https://mozilla.com".toUri(),
VerificationStatus.PENDING
)).joinBlocking()
assertEquals(View.GONE, toolbar.visibility)
assertFalse(toolbarVisible)
}
private fun mockCustomTabState(vararg origins: String) = CustomTabState(
......
......@@ -55,7 +55,7 @@ permalink: /changelog/
* Added `ContentState.pictureInPictureEnabled` to track if Picture in Picture mode is in use.
* **feature-pwa**
* ⚠️ **This is a breaking change**: `WebAppHideToolbarFeature` now takes `BrowserStore` instead of `SessionManager`. `trustedScopes` is now derived from `CustomTabsServiceStore` and `WebAppManifest`.
* ⚠️ **This is a breaking change**: `WebAppHideToolbarFeature` now takes `BrowserStore` instead of `SessionManager`. `trustedScopes` is now derived from `CustomTabsServiceStore` and `WebAppManifest`. `setToolbarVisibility` should now be used set the visibility of the toolbar.
* ⚠️ **This is a breaking change**: `onToolbarVisibilityChange` has been removed. You should now observe `BrowserStore` instead.
# 44.0.0
......
......@@ -8,6 +8,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.fragment_browser.view.*
import mozilla.components.concept.engine.manifest.WebAppManifest
import mozilla.components.feature.customtabs.CustomTabWindowFeature
......@@ -51,12 +52,13 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
hideToolbarFeature.set(
feature = WebAppHideToolbarFeature(
layout.toolbar,
components.store,
components.customTabsStore,
sessionId,
manifest
),
) { toolbarVisible ->
layout.toolbar.isVisible = toolbarVisible
},
owner = this,
view = layout.toolbar)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment