Commit fb36d5b0 authored by Christian Sadilek's avatar Christian Sadilek
Browse files

Closes #2985: Launch reader view in extension page

parent 5bf5c424
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import mozilla.components.concept.engine.EngineSessionState
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.base.memory.MemoryConsumer
import mozilla.components.support.base.observer.Observable
import mozilla.components.support.ktx.kotlin.isExtensionUrl
import java.lang.IllegalArgumentException

/**
@@ -62,10 +63,17 @@ class SessionManager(
                this.engineObserver = EngineObserver(session, store).also { observer ->
                    engineSession.register(observer)
                    if (!sessionRestored && !skipLoading) {
                        if (session.url.isExtensionUrl()) {
                            // The parent tab/session is used as a referrer which is not accurate
                            // for extension pages. The extension page is not loaded by the parent
                            // tab, but opened by an extension e.g. via browser.tabs.update.
                            engineSession.loadUrl(session.url)
                        } else {
                            engineSession.loadUrl(session.url, parentEngineSession)
                        }
                    }
                }
            }

            store?.syncDispatch(LinkEngineSessionAction(session.id, engineSession))
        }
@@ -292,6 +300,9 @@ class SessionManager(
            item.engineSessionState?.let { store?.syncDispatch(UpdateEngineSessionStateAction(item.session.id, it)) }
            item.readerState?.let {
                store?.syncDispatch(ReaderAction.UpdateReaderActiveAction(item.session.id, it.active))
                it.activeUrl?.let { activeUrl ->
                    store?.syncDispatch(ReaderAction.UpdateReaderActiveUrlAction(item.session.id, activeUrl))
                }
            }
        }
    }
+8 −2
Original line number Diff line number Diff line
@@ -51,6 +51,9 @@ class SnapshotSerializer(

        val sessionJson = serializeSession(item.session)
        sessionJson.put(Keys.SESSION_READER_MODE_KEY, item.readerState?.active ?: false)
        if (item.readerState?.active == true && item.readerState.activeUrl != null) {
            sessionJson.put(Keys.SESSION_READER_MODE_ACTIVE_URL_KEY, item.readerState.activeUrl)
        }
        itemJson.put(Keys.SESSION_KEY, sessionJson)

        val engineSessionState = if (item.engineSessionState != null) {
@@ -84,8 +87,10 @@ class SnapshotSerializer(
        val sessionJson = json.getJSONObject(Keys.SESSION_KEY)
        val engineSessionJson = json.getJSONObject(Keys.ENGINE_SESSION_KEY)
        val session = deserializeSession(sessionJson, restoreSessionIds, restoreParentIds)
        val readerState =
            ReaderState(active = sessionJson.optBoolean(Keys.SESSION_READER_MODE_KEY, false))
        val readerState = ReaderState(
            active = sessionJson.optBoolean(Keys.SESSION_READER_MODE_KEY, false),
            activeUrl = sessionJson.tryGetString(Keys.SESSION_READER_MODE_ACTIVE_URL_KEY)
        )
        val engineState = engine.createSessionState(engineSessionJson)

        return SessionManager.Snapshot.Item(
@@ -144,6 +149,7 @@ private object Keys {
    const val SESSION_CONTEXT_ID_KEY = "contextId"
    const val SESSION_PARENT_UUID_KEY = "parentUuid"
    const val SESSION_READER_MODE_KEY = "readerMode"
    const val SESSION_READER_MODE_ACTIVE_URL_KEY = "readerModeArticleUrl"
    const val SESSION_TITLE = "title"

    const val SESSION_KEY = "session"
+7 −2
Original line number Diff line number Diff line
@@ -410,7 +410,10 @@ class SessionManagerMigrationTest {
        }

        store.dispatch(ReaderAction.UpdateReaderActiveAction(session2.id, true)).joinBlocking()
        assertEquals(ReaderState(active = true), store.state.findTab(session2.id)?.readerState)
        store.dispatch(ReaderAction.UpdateReaderActiveUrlAction(session2.id, "blog.mozilla.org/1")).joinBlocking()
        assertEquals(ReaderState(active = true, activeUrl = "blog.mozilla.org/1"),
            store.state.findTab(session2.id)?.readerState
        )

        val snapshot = manager.createSnapshot()
        manager.removeAll()
@@ -419,7 +422,9 @@ class SessionManagerMigrationTest {

        manager.restore(snapshot)
        assertEquals(ReaderState(active = false), store.state.findTab(session1.id)?.readerState)
        assertEquals(ReaderState(active = true), store.state.findTab(session2.id)?.readerState)
        assertEquals(ReaderState(active = true, activeUrl = "blog.mozilla.org/1"),
            store.state.findTab(session2.id)?.readerState
        )
    }

    @Test
+25 −0
Original line number Diff line number Diff line
@@ -707,6 +707,31 @@ class SessionManagerTest {
        verify(engineSession).loadUrl(session.url, parentEngineSession, EngineSession.LoadUrlFlags.none())
    }

    @Test
    fun `parent is not provided when linking engine session for extension page`() {
        val engine: Engine = mock()

        val parent = Session(id = "parent", initialUrl = "")
        val parentEngineSession: EngineSession = mock()
        val session = Session("moz-extension://test-1234")
        session.parentId = parent.id
        val engineSession: EngineSession = mock()

        val sessionManager = SessionManager(engine)
        sessionManager.add(parent)
        sessionManager.add(session)

        doReturn(parentEngineSession, engineSession).`when`(engine).createSession(false)

        assertEquals(parentEngineSession, sessionManager.getOrCreateEngineSession(parent))
        assertEquals(parentEngineSession, parent.engineSessionHolder.engineSession)

        assertEquals(engineSession, sessionManager.getOrCreateEngineSession(session))
        assertEquals(engineSession, session.engineSessionHolder.engineSession)

        verify(engineSession).loadUrl(session.url, null, EngineSession.LoadUrlFlags.none())
    }

    @Test
    fun `removing a session unlinks the engine session`() {
        val engine: Engine = mock()
+20 −2
Original line number Diff line number Diff line
@@ -99,13 +99,13 @@ class SnapshotSerializerTest {
        }

        val serializer = SnapshotSerializer()
        val json = serializer.itemToJSON(
        var json = serializer.itemToJSON(
            Snapshot.Item(
                originalSession,
                readerState = ReaderState(active = true)
            )
        )
        val restoredItem = serializer.itemFromJSON(engine, json)
        var restoredItem = serializer.itemFromJSON(engine, json)

        assertEquals("https://www.mozilla.org", restoredItem.session.url)
        assertEquals(Session.Source.RESTORED, restoredItem.session.source)
@@ -113,6 +113,24 @@ class SnapshotSerializerTest {
        assertEquals("test-context-id", restoredItem.session.contextId)
        assertEquals("Hello World", restoredItem.session.title)
        assertEquals(ReaderState(active = true), restoredItem.readerState)

        json = serializer.itemToJSON(
            Snapshot.Item(
                originalSession,
                readerState = ReaderState(active = true, activeUrl = "https://blog.mozilla.org/123")
            )
        )
        restoredItem = serializer.itemFromJSON(engine, json)
        assertEquals(ReaderState(active = true, activeUrl = "https://blog.mozilla.org/123"), restoredItem.readerState)

        json = serializer.itemToJSON(
            Snapshot.Item(
                originalSession,
                readerState = ReaderState(active = false, activeUrl = "https://blog.mozilla.org/123")
            )
        )
        restoredItem = serializer.itemFromJSON(engine, json)
        assertEquals(ReaderState(), restoredItem.readerState)
    }

    @Test
Loading