Skip to content
This repository has been archived by the owner on Apr 17, 2021. It is now read-only.

Commit

Permalink
Issue #929: Use browser-session component for browser state.
Browse files Browse the repository at this point in the history
  • Loading branch information
pocmo committed Jul 20, 2018
1 parent 0fda8e2 commit f627a6d
Show file tree
Hide file tree
Showing 31 changed files with 349 additions and 848 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ dependencies {
implementation "com.android.support:leanback-v17:$support_libraries_version"
implementation "com.android.support.constraint:constraint-layout:$constrained_layout_version"

implementation "android.arch.lifecycle:extensions:$architecture_components_version"

implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.picasso:picasso:2.71828', {
// We temporarily don't include the packaged the support libs to avoid version mismatch.
Expand All @@ -165,6 +163,8 @@ dependencies {
transitive = false
}

implementation "org.mozilla.components:session:$moz_components_version"
implementation "org.mozilla.components:engine:$moz_components_version"
implementation "org.mozilla.components:telemetry:$moz_components_version"
implementation "org.mozilla.photon:colors:$moz_components_version"
implementation "org.mozilla.photon:fonts:$moz_components_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import android.util.AttributeSet
import android.view.View
import com.amazon.android.webkit.AmazonWebChromeClient
import com.amazon.android.webkit.AmazonWebView
import mozilla.components.browser.session.Session
import org.mozilla.focus.ext.deleteData
import org.mozilla.focus.ext.savedWebViewState
import org.mozilla.focus.iwebview.FirefoxAmazonFocusedDOMElementCache
import org.mozilla.focus.iwebview.IWebView
import org.mozilla.focus.session.Session
import org.mozilla.focus.utils.UrlUtils

private val uiHandler = Handler(Looper.getMainLooper())
Expand Down Expand Up @@ -101,10 +102,10 @@ internal class FirefoxAmazonWebView(
}

override fun restoreWebViewState(session: Session) {
val stateData = session.webViewState
val stateData = session.savedWebViewState

val backForwardList = if (stateData != null) super.restoreState(stateData) else null
val desiredURL = session.url.value
val desiredURL = session.url

client.restoreState(stateData)
client.notifyCurrentURL(desiredURL)
Expand Down Expand Up @@ -135,7 +136,7 @@ internal class FirefoxAmazonWebView(
super.saveState(stateData)
client.saveState(this, stateData)

session.saveWebViewState(stateData)
session.savedWebViewState = stateData
}

override fun setBlockingEnabled(enabled: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mozilla.focus.session.Session;
import org.mozilla.gecko.GeckoView;
import org.mozilla.gecko.GeckoViewSettings;

import kotlin.NotImplementedError;
import mozilla.components.browser.session.Session;

/**
* WebViewProvider implementation for creating a Gecko based implementation of IWebView.
Expand Down Expand Up @@ -234,6 +234,7 @@ public void removeJavascriptInterface(@Nullable String interfaceName) {

}


@Override
public void restoreWebViewState(Session session) {
// TODO: restore navigation history, and reopen previously opened page
Expand Down
38 changes: 38 additions & 0 deletions app/src/main/java/org/mozilla/focus/Components.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* 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 org.mozilla.focus

import android.content.Context
import android.util.AttributeSet
import mozilla.components.browser.session.SessionManager
import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineView

/**
* Helper class for lazily instantiating and keeping references to components needed by the
* application.
*/
class Components {
val sessionManager by lazy { SessionManager(DummyEngine()) }
}

/**
* We are not using an "Engine" implementation yet. Therefore we create this dummy that we pass to
* the <code>SessionManager</code> for now.
*/
private class DummyEngine : Engine {
override fun createSession(): EngineSession {
throw NotImplementedError()
}

override fun createView(context: Context, attrs: AttributeSet?): EngineView {
throw NotImplementedError()
}

override fun name(): String {
throw NotImplementedError()
}
}
10 changes: 10 additions & 0 deletions app/src/main/java/org/mozilla/focus/FocusApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ class FocusApplication : LocaleAwareApplication() {
lateinit var visibilityLifeCycleCallback: VisibilityLifeCycleCallback
private set

/**
* Reference to components needed by the application.
*
* We create this instance lazily because at the time FocusApplication gets constructed it is
* not a valid Context object just yet (The Android system needs to call attachBaseContext()
* first). Therefore we delay the creation so that the components can access and use the
* application context at the time they get created.
*/
val components by lazy { Components() }

override fun onCreate() {
super.onCreate()

Expand Down
50 changes: 33 additions & 17 deletions app/src/main/java/org/mozilla/focus/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ import android.view.View
import com.amazon.android.webkit.AmazonWebKitFactories
import com.amazon.android.webkit.AmazonWebKitFactory
import kotlinx.android.synthetic.main.activity_main.*
import org.mozilla.focus.architecture.NonNullObserver
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import org.mozilla.focus.browser.BrowserFragment
import org.mozilla.focus.browser.BrowserFragment.Companion.APP_URL_HOME
import org.mozilla.focus.browser.VideoVoiceCommandMediaSession
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.toSafeIntent
import org.mozilla.focus.home.pocket.Pocket
import org.mozilla.focus.home.pocket.PocketOnboardingActivity
import org.mozilla.focus.iwebview.IWebView
import org.mozilla.focus.iwebview.WebViewProvider
import org.mozilla.focus.locale.LocaleAwareAppCompatActivity
import org.mozilla.focus.session.Session
import org.mozilla.focus.session.SessionManager
import org.mozilla.focus.session.Source
import org.mozilla.focus.telemetry.SentryWrapper
import org.mozilla.focus.telemetry.TelemetryWrapper
Expand All @@ -43,12 +43,31 @@ interface MediaSessionHolder {

class MainActivity : LocaleAwareAppCompatActivity(), OnUrlEnteredListener, MediaSessionHolder {

private val sessionManager = SessionManager.getInstance()

// There should be at most one MediaSession per process, hence it's in MainActivity.
// We crash if we init MediaSession at init time, hence lateinit.
override lateinit var videoVoiceCommandMediaSession: VideoVoiceCommandMediaSession

private val sessionObserver = object : SessionManager.Observer {
override fun onSessionSelected(session: Session) {
ScreenController.showBrowserScreenForCurrentSession(supportFragmentManager, session)
}

override fun onSessionRemoved(session: Session) {
if (components.sessionManager.sessions.isEmpty()) {
onNoActiveSession()
}
}

override fun onAllSessionsRemoved() {
onNoActiveSession()
}

private fun onNoActiveSession() {
// There's no active session. Start a new session with "homepage".
ScreenController.showBrowserScreenForUrl(this@MainActivity, supportFragmentManager, APP_URL_HOME, Source.NONE)
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Expand All @@ -66,17 +85,14 @@ class MainActivity : LocaleAwareAppCompatActivity(), OnUrlEnteredListener, Media
setContentView(R.layout.activity_main)

IntentValidator.validateOnCreate(this, intent, savedInstanceState, ::onValidBrowserIntent)
sessionManager.sessions.observe(this, object : NonNullObserver<List<Session>>() {
public override fun onValueChanged(value: List<Session>) {
val sessions = value
if (sessions.isEmpty()) {
// There's no active session. Start a new session with "homepage".
ScreenController.showBrowserScreenForUrl(supportFragmentManager, APP_URL_HOME, Source.NONE)
} else {
ScreenController.showBrowserScreenForCurrentSession(supportFragmentManager, sessionManager)
}
}
})

components.sessionManager.register(sessionObserver, owner = this)

if (components.sessionManager.sessions.isEmpty()) {
ScreenController.showBrowserScreenForUrl(this@MainActivity, supportFragmentManager, APP_URL_HOME, Source.NONE)
} else {
ScreenController.showBrowserScreenForCurrentSession(supportFragmentManager, components.sessionManager.selectedSession)
}

if (Settings.getInstance(this@MainActivity).shouldShowPocketOnboarding()) {
val onboardingIntents =
Expand All @@ -97,7 +113,7 @@ class MainActivity : LocaleAwareAppCompatActivity(), OnUrlEnteredListener, Media
}

private fun onValidBrowserIntent(url: String, source: Source) {
ScreenController.showBrowserScreenForUrl(supportFragmentManager, url, source)
ScreenController.showBrowserScreenForUrl(this, supportFragmentManager, url, source)
}

override fun applyLocale() {
Expand Down
21 changes: 12 additions & 9 deletions app/src/main/java/org/mozilla/focus/ScreenController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ package org.mozilla.focus
import android.content.Context
import android.support.v4.app.FragmentManager
import android.text.TextUtils
import mozilla.components.browser.session.Session
import org.mozilla.focus.browser.BrowserFragment
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.source
import org.mozilla.focus.home.pocket.Pocket
import org.mozilla.focus.home.pocket.PocketVideoFragment
import org.mozilla.focus.session.SessionManager
import org.mozilla.focus.session.Source
import org.mozilla.focus.telemetry.TelemetryWrapper
import org.mozilla.focus.telemetry.UrlTextInputLocation
Expand All @@ -33,7 +35,7 @@ object ScreenController {
val isUrl = UrlUtils.isUrl(urlStr)
val updatedUrlStr = if (isUrl) UrlUtils.normalize(urlStr) else UrlUtils.createSearchUrl(context, urlStr)

showBrowserScreenForUrl(fragmentManager, updatedUrlStr, Source.USER_ENTERED)
showBrowserScreenForUrl(context, fragmentManager, updatedUrlStr, Source.USER_ENTERED)

if (isTextInput) {
// Non-text input events are handled at the source, e.g. home tile click events.
Expand All @@ -56,11 +58,9 @@ object ScreenController {
.commit()
}

fun showBrowserScreenForCurrentSession(fragmentManager: FragmentManager, sessionManager: SessionManager) {
val currentSession = sessionManager.currentSession

fun showBrowserScreenForCurrentSession(fragmentManager: FragmentManager, session: Session) {
val fragment = fragmentManager.findFragmentByTag(BrowserFragment.FRAGMENT_TAG) as BrowserFragment?
if (fragment != null && fragment.session.isSameAs(currentSession)) {
if (fragment != null && fragment.session == session) {
// There's already a BrowserFragment displaying this session.
return
}
Expand All @@ -69,11 +69,11 @@ object ScreenController {
fragmentManager
.beginTransaction()
.replace(R.id.container,
BrowserFragment.createForSession(currentSession), BrowserFragment.FRAGMENT_TAG)
BrowserFragment.createForSession(session), BrowserFragment.FRAGMENT_TAG)
.commit()
}

fun showBrowserScreenForUrl(fragmentManager: FragmentManager, url: String, source: Source) {
fun showBrowserScreenForUrl(context: Context, fragmentManager: FragmentManager, url: String, source: Source) {
// This code is not correct:
// - We only support one session but it creates a new session when there's no BrowserFragment
// such as each time we open a URL from the home screen.
Expand All @@ -89,7 +89,10 @@ object ScreenController {
// for visibility in addition to existence.
browserFragment.loadUrl(url)
} else {
SessionManager.getInstance().createSession(source, url)
val session = Session(url).apply {
this.source = source
}
context.components.sessionManager.add(session)
}
}

Expand Down
16 changes: 8 additions & 8 deletions app/src/main/java/org/mozilla/focus/SettingsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import android.view.ViewGroup
import android.view.accessibility.AccessibilityManager
import kotlinx.android.synthetic.main.fragment_settings.*
import org.mozilla.focus.browser.InfoActivity
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.getAccessibilityManager
import org.mozilla.focus.ext.isVoiceViewEnabled
import org.mozilla.focus.session.SessionManager
import org.mozilla.focus.telemetry.DataUploadPreference
import org.mozilla.focus.telemetry.TelemetryWrapper

Expand Down Expand Up @@ -46,13 +46,13 @@ class SettingsFragment : Fragment() {
builder1.setCancelable(true)

builder1.setPositiveButton(
getString(R.string.action_ok),
{ dialog, _ ->
settingsWebView.cleanup()
SessionManager.getInstance().removeAllSessions()
dialog.cancel()
TelemetryWrapper.clearDataEvent()
})
getString(R.string.action_ok)
) { dialog, _ ->
settingsWebView.cleanup()
context!!.components.sessionManager.removeAll()
dialog.cancel()
TelemetryWrapper.clearDataEvent()
}

builder1.setNegativeButton(
getString(R.string.action_cancel),
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit f627a6d

Please sign in to comment.