From 4c4f344a971e08768ad57fd9e57841d4f9e7ad4b Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Fri, 18 Jan 2019 15:33:40 -0800 Subject: [PATCH] For #131 - Loads mozilla.org in the browser fragment --- app/build.gradle | 8 ++ .../java/org/mozilla/fenix/HomeActivity.kt | 19 ++++ .../mozilla/fenix/browser/BrowserFragment.kt | 35 ++++++++ .../java/org/mozilla/fenix/components/Core.kt | 87 +++++++++++++++++++ .../org/mozilla/fenix/home/HomeFragment.kt | 6 +- app/src/main/res/layout/fragment_browser.xml | 69 +++++++++------ buildSrc/src/main/java/Dependencies.kt | 11 ++- 7 files changed, 205 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/components/Core.kt diff --git a/app/build.gradle b/app/build.gradle index 4d7bd22de..cad00c1ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,9 +68,17 @@ dependencies { implementation Deps.androidx_appcompat implementation Deps.androidx_constraintlayout + implementation Deps.mozilla_concept_engine + implementation Deps.mozilla_concept_storage + implementation Deps.mozilla_browser_awesomebar + implementation Deps.mozilla_browser_engine_gecko_nightly + implementation Deps.mozilla_browser_session implementation Deps.mozilla_browser_toolbar + implementation Deps.mozilla_feature_intent + implementation Deps.mozilla_feature_session + testImplementation Deps.junit androidTestImplementation Deps.tools_test_runner androidTestImplementation Deps.tools_espresso_core diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index e17d005c4..240c8476d 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -4,12 +4,31 @@ package org.mozilla.fenix +import android.content.Context import android.os.Bundle +import android.util.AttributeSet +import android.view.View import androidx.appcompat.app.AppCompatActivity +import mozilla.components.concept.engine.EngineView +import mozilla.components.feature.intent.IntentProcessor +import mozilla.components.support.utils.SafeIntent +import org.mozilla.fenix.components.Core class HomeActivity : AppCompatActivity() { + + val core by lazy { Core(this) } + val sessionId by lazy { + SafeIntent(intent).getStringExtra(IntentProcessor.ACTIVE_SESSION_ID) + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_home) } + + override fun onCreateView(parent: View?, name: String?, context: Context, attrs: AttributeSet?): View? = + when (name) { + EngineView::class.java.name -> core.engine.createView(context, attrs).asView() + else -> super.onCreateView(parent, name, context, attrs) + } } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 70319c8a6..54c76ddaa 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -4,18 +4,53 @@ package org.mozilla.fenix.browser import android.os.Bundle +import android.transition.TransitionInflater import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import kotlinx.android.synthetic.main.fragment_browser.* +import mozilla.components.feature.intent.IntentProcessor +import mozilla.components.feature.session.SessionFeature +import mozilla.components.feature.session.SessionUseCases +import mozilla.components.support.utils.SafeIntent +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R class BrowserFragment : Fragment() { + private lateinit var sessionFeature: SessionFeature + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_browser, container, false) } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + + val sessionManager = (activity as HomeActivity).core.sessionManager + val sessionId = (activity as HomeActivity).sessionId + + sessionFeature = SessionFeature( + sessionManager, + SessionUseCases(sessionManager), + engineView, + sessionId) + + lifecycle.addObservers(sessionFeature) + } } + +private fun Lifecycle.addObservers(vararg observers: LifecycleObserver) = observers.forEach { addObserver(it) } diff --git a/app/src/main/java/org/mozilla/fenix/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt new file mode 100644 index 000000000..64d94503a --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -0,0 +1,87 @@ +/* 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.fenix.components + +import android.content.Context +import android.content.SharedPreferences +import android.preference.PreferenceManager +import mozilla.components.browser.engine.gecko.GeckoEngine +import mozilla.components.browser.session.Session +import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.session.storage.SessionStorage +import mozilla.components.concept.engine.DefaultSettings +import mozilla.components.concept.engine.Engine +import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy +import java.util.concurrent.TimeUnit + +/** + * Component group for all core browser functionality. + */ +class Core(private val context: Context) { + + /** + * The browser engine component initialized based on the build + * configuration (see build variants). + */ + val engine: Engine by lazy { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + + val defaultSettings = DefaultSettings( + remoteDebuggingEnabled = false, + testingModeEnabled = false, + trackingProtectionPolicy = createTrackingProtectionPolicy(prefs) + ) + GeckoEngine(context, defaultSettings) + } + + /** + * The session manager component provides access to a centralized registry of + * all browser sessions (i.e. tabs). It is initialized here to persist and restore + * sessions from the [SessionStorage], and with a default session (about:blank) in + * case all sessions/tabs are closed. + */ + val sessionManager by lazy { + val sessionStorage = SessionStorage(context, engine) + + SessionManager(engine, defaultSession = { Session("about:blank") }).apply { + sessionStorage.restore()?.let { snapshot -> restore(snapshot) } + + if (size == 0) { + val initialSession = Session("https://www.mozilla.org") + add(initialSession) + } + + sessionStorage.autoSave(this) + .periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS) + .whenGoingToBackground() + .whenSessionsChange() + } + } + + /** + * Constructs a [TrackingProtectionPolicy] based on current preferences. + * + * @param prefs the shared preferences to use when reading tracking + * protection settings. + * @param normalMode whether or not tracking protection should be enabled + * in normal browsing mode, defaults to the current preference value. + * @param privateMode whether or not tracking protection should be enabled + * in private browsing mode, default to the current preference value. + * @return the constructed tracking protection policy based on preferences. + */ + fun createTrackingProtectionPolicy( + prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context), + normalMode: Boolean = true, + privateMode: Boolean = true + ): TrackingProtectionPolicy { + + return when { + normalMode && privateMode -> TrackingProtectionPolicy.all() + normalMode && !privateMode -> TrackingProtectionPolicy.all().forRegularSessionsOnly() + !normalMode && privateMode -> TrackingProtectionPolicy.all().forPrivateSessionsOnly() + else -> TrackingProtectionPolicy.none() + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 74c50f379..62909f53a 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -17,6 +17,8 @@ import android.widget.TextView import androidx.annotation.RequiresApi import androidx.core.view.ViewCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver import androidx.navigation.Navigation import androidx.navigation.fragment.FragmentNavigator import androidx.recyclerview.widget.LinearLayoutManager @@ -44,7 +46,7 @@ class HomeFragment : Fragment() { val extras = FragmentNavigator.Extras.Builder().addSharedElement( toolbar_wrapper, ViewCompat.getTransitionName(toolbar_wrapper)!! ).build() - Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_searchFragment, null, null, extras) + Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_browserFragment, null, null, extras) } session_list.apply { @@ -84,4 +86,4 @@ private class SessionsAdapter(val context: Context) : RecyclerView.Adapter - + + app:layout_constraintStart_toStartOf="parent"> + + + + + + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="40dp" + android:layout_margin="8dp" + android:background="@android:color/white" + android:clickable="true" + android:focusable="true" + android:focusableInTouchMode="true" /> - \ No newline at end of file + \ No newline at end of file diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index ade525c88..13e6f9358 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -5,7 +5,7 @@ private object Versions { const val kotlin = "1.3.11" const val android_gradle_plugin = "3.2.1" - const val geckoNightly = "66.0.20181217093726" + const val geckoNightly = "66.0.20190111093148" const val androidx_appcompat = "1.0.2" const val androidx_constraint_layout = "2.0.0-alpha3" @@ -32,9 +32,18 @@ object Deps { const val androidx_appcompat = "androidx.appcompat:appcompat:${Versions.androidx_appcompat}" const val androidx_constraintlayout = "androidx.constraintlayout:constraintlayout:${Versions.androidx_constraint_layout}" + const val mozilla_concept_engine = "org.mozilla.components:concept-engine:${Versions.mozilla_android_components}" + const val mozilla_concept_storage = "org.mozilla.components:concept-storage:${Versions.mozilla_android_components}" + const val mozilla_browser_awesomebar = "org.mozilla.components:browser-awesomebar:${Versions.mozilla_android_components}" + const val mozilla_browser_engine_gecko_nightly = "org.mozilla.components:browser-engine-gecko-nightly:${Versions.mozilla_android_components}" + const val mozilla_browser_session = "org.mozilla.components:browser-session:${Versions.mozilla_android_components}" const val mozilla_browser_toolbar = "org.mozilla.components:browser-toolbar:${Versions.mozilla_android_components}" + const val mozilla_feature_intent = "org.mozilla.components:feature-intent:${Versions.mozilla_android_components}" + const val mozilla_feature_session = "org.mozilla.components:feature-session:${Versions.mozilla_android_components}" + const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}" + const val junit = "junit:junit:${Versions.junit}" const val tools_test_runner = "com.android.support.test:runner:${Versions.test_tools}" const val tools_espresso_core = "com.android.support.test.espresso:espresso-core:${Versions.espresso_core}"