diff --git a/components/browser/state/build.gradle b/components/browser/state/build.gradle index 58c8bea9c31..b41f43593f6 100644 --- a/components/browser/state/build.gradle +++ b/components/browser/state/build.gradle @@ -30,6 +30,7 @@ dependencies { api project(':lib-state') implementation project(':concept-engine') + implementation project(':concept-storage') implementation project(':support-utils') implementation project(':support-ktx') diff --git a/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt b/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt index 2be84db9500..306ae55e851 100644 --- a/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt +++ b/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt @@ -45,6 +45,7 @@ import mozilla.components.concept.engine.search.SearchRequest import mozilla.components.concept.engine.webextension.WebExtensionBrowserAction import mozilla.components.concept.engine.webextension.WebExtensionPageAction import mozilla.components.concept.engine.window.WindowRequest +import mozilla.components.concept.storage.HistoryMetadataKey import mozilla.components.lib.state.Action import mozilla.components.support.base.android.Clock import java.util.Locale @@ -1042,6 +1043,20 @@ sealed class ContainerAction : BrowserAction() { data class RemoveContainerAction(val contextId: String) : ContainerAction() } +/** + * [BrowserAction] implementations related to updating [TabSessionState.historyMetadata]. + */ +sealed class HistoryMetadataAction : BrowserAction() { + + /** + * Associates a tab with a history metadata record described by the provided [historyMetadataKey]. + */ + data class SetHistoryMetadataKeyAction( + val tabId: String, + val historyMetadataKey: HistoryMetadataKey + ) : HistoryMetadataAction() +} + /** * [BrowserAction] implementations related to updating search engines in [SearchState]. */ diff --git a/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/BrowserStateReducer.kt b/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/BrowserStateReducer.kt index 8d9ccc64efc..6d9df956115 100644 --- a/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/BrowserStateReducer.kt +++ b/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/BrowserStateReducer.kt @@ -12,6 +12,7 @@ import mozilla.components.browser.state.action.CrashAction import mozilla.components.browser.state.action.CustomTabListAction import mozilla.components.browser.state.action.DownloadAction import mozilla.components.browser.state.action.EngineAction +import mozilla.components.browser.state.action.HistoryMetadataAction import mozilla.components.browser.state.action.InitAction import mozilla.components.browser.state.action.LastAccessAction import mozilla.components.browser.state.action.MediaSessionAction @@ -61,6 +62,7 @@ internal object BrowserStateReducer { is UndoAction -> UndoReducer.reduce(state, action) is ShareInternetResourceAction -> ShareInternetResourceStateReducer.reduce(state, action) is LocaleAction -> LocaleStateReducer.reduce(state, action) + is HistoryMetadataAction -> HistoryMetadataReducer.reduce(state, action) } } } diff --git a/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/HistoryMetadataReducer.kt b/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/HistoryMetadataReducer.kt new file mode 100644 index 00000000000..7c6ccee68f1 --- /dev/null +++ b/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/HistoryMetadataReducer.kt @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package mozilla.components.browser.state.reducer + +import mozilla.components.browser.state.action.HistoryMetadataAction +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.TabSessionState +import mozilla.components.concept.storage.HistoryMetadataKey + +internal object HistoryMetadataReducer { + + /** + * [HistoryMetadataAction] reducer function for modifying [TabSessionState.historyMetadata]. + */ + fun reduce(state: BrowserState, action: HistoryMetadataAction): BrowserState { + return when (action) { + is HistoryMetadataAction.SetHistoryMetadataKeyAction -> + state.updateHistoryMetadataKey(action.tabId, action.historyMetadataKey) + } + } +} + +private fun BrowserState.updateHistoryMetadataKey( + tabId: String, + key: HistoryMetadataKey +): BrowserState { + return copy( + tabs = tabs.updateTabs(tabId) { current -> + current.copy(historyMetadata = key) + } ?: tabs + ) +} diff --git a/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt b/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt index 7c8faa815f6..d09e4fc21bb 100644 --- a/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt +++ b/components/browser/state/src/main/java/mozilla/components/browser/state/state/TabSessionState.kt @@ -7,6 +7,7 @@ package mozilla.components.browser.state.state import android.graphics.Bitmap import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.EngineSessionState +import mozilla.components.concept.storage.HistoryMetadataKey import java.util.UUID /** @@ -36,7 +37,8 @@ data class TabSessionState( override val source: SessionState.Source = SessionState.Source.NONE, val parentId: String? = null, val lastAccess: Long = 0L, - val readerState: ReaderState = ReaderState() + val readerState: ReaderState = ReaderState(), + val historyMetadata: HistoryMetadataKey? = null ) : SessionState { override fun createCopy( diff --git a/components/browser/state/src/test/java/mozilla/components/browser/state/action/HistoryMetadataActionTest.kt b/components/browser/state/src/test/java/mozilla/components/browser/state/action/HistoryMetadataActionTest.kt new file mode 100644 index 00000000000..d560a397252 --- /dev/null +++ b/components/browser/state/src/test/java/mozilla/components/browser/state/action/HistoryMetadataActionTest.kt @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package mozilla.components.browser.state.action + +import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.createTab +import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.storage.HistoryMetadataKey +import mozilla.components.support.test.ext.joinBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test + +class HistoryMetadataActionTest { + + @Test + fun `SetHistoryMetadataKeyAction - Associates tab with history metadata`() { + val tab = createTab("https://www.mozilla.org") + val store = BrowserStore(BrowserState(tabs = listOf(tab))) + assertNull(store.state.findTab(tab.id)?.historyMetadata) + + val historyMetadata = HistoryMetadataKey( + url = tab.content.url, + referrerUrl = "https://firefox.com" + ) + + store.dispatch(HistoryMetadataAction.SetHistoryMetadataKeyAction(tab.id, historyMetadata)).joinBlocking() + assertEquals(historyMetadata, store.state.findTab(tab.id)?.historyMetadata) + } +}