From 480ae93a72365fa8034f36efdba76cef7e0253d4 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Wed, 23 Jan 2019 13:39:53 -0800 Subject: [PATCH] For #141 - Adds autocomplete ot the search screen - Adds convenience extensions to Context and Fragment - Imports more components from Android Components --- app/build.gradle | 3 ++ app/src/main/AndroidManifest.xml | 1 + .../org/mozilla/fenix/FenixApplication.kt | 8 ++++ .../java/org/mozilla/fenix/HomeActivity.kt | 12 +----- .../mozilla/fenix/browser/BrowserFragment.kt | 6 +-- .../mozilla/fenix/components/Components.kt | 12 ++++++ .../org/mozilla/fenix/components/Search.kt | 24 +++++++++++ .../org/mozilla/fenix/components/UseCases.kt | 21 ++++++++++ .../components/toolbar/ToolbarIntegration.kt | 42 +++++++++++++++++++ .../java/org/mozilla/fenix/ext/Context.kt | 11 +++++ .../java/org/mozilla/fenix/ext/Fragment.kt | 7 ++++ .../org/mozilla/fenix/home/HomeFragment.kt | 2 +- .../mozilla/fenix/search/SearchFragment.kt | 11 +++++ buildSrc/src/main/java/Dependencies.kt | 2 + 14 files changed, 148 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/FenixApplication.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/Components.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/Search.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/UseCases.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt create mode 100644 app/src/main/java/org/mozilla/fenix/ext/Context.kt create mode 100644 app/src/main/java/org/mozilla/fenix/ext/Fragment.kt diff --git a/app/build.gradle b/app/build.gradle index 9695b4dd0..34263bcce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,12 +72,14 @@ dependencies { implementation Deps.mozilla_concept_storage implementation Deps.mozilla_browser_awesomebar + implementation Deps.mozilla_browser_domains 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 + implementation Deps.mozilla_feature_toolbar implementation Deps.mozilla_support_ktx @@ -89,4 +91,5 @@ dependencies { x86Implementation Deps.geckoview_nightly_x86 implementation Deps.androidx_legacy implementation Deps.android_arch_navigation + implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha09' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b88bfc8e4..a22812142 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" + android:name=".FenixApplication" android:theme="@style/LightAppTheme"> diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt new file mode 100644 index 000000000..dd38cdb3e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -0,0 +1,8 @@ +package org.mozilla.fenix + +import android.app.Application +import org.mozilla.fenix.components.Components + +class FenixApplication : Application() { + val components by lazy { Components(this) } +} diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 240c8476d..08aabd103 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -10,17 +10,9 @@ 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 +import org.mozilla.fenix.ext.components 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) @@ -28,7 +20,7 @@ class HomeActivity : AppCompatActivity() { override fun onCreateView(parent: View?, name: String?, context: Context, attrs: AttributeSet?): View? = when (name) { - EngineView::class.java.name -> core.engine.createView(context, attrs).asView() + EngineView::class.java.name -> components.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 0daa96611..34b0a5a7b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -13,8 +13,8 @@ import kotlinx.android.synthetic.main.fragment_browser.* import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SessionUseCases import mozilla.components.support.ktx.android.arch.lifecycle.addObservers -import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R +import org.mozilla.fenix.ext.requireComponents class BrowserFragment : Fragment() { @@ -37,8 +37,8 @@ class BrowserFragment : Fragment() { super.onViewCreated(view, savedInstanceState) - val sessionManager = (activity as HomeActivity).core.sessionManager - val sessionId = (activity as HomeActivity).sessionId + val sessionManager = requireComponents.core.sessionManager + val sessionId = "1" sessionFeature = SessionFeature( sessionManager, diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt new file mode 100644 index 000000000..a5edfbe35 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -0,0 +1,12 @@ +package org.mozilla.fenix.components + +import android.content.Context + +/** + * Provides access to all components. + */ +class Components(private val context: Context) { + val core by lazy { Core(context) } + val search by lazy { Search(context) } + val useCases by lazy { UseCases(context, core.sessionManager, search.searchEngineManager) } +} \ No newline at end of file diff --git a/app/src/main/java/org/mozilla/fenix/components/Search.kt b/app/src/main/java/org/mozilla/fenix/components/Search.kt new file mode 100644 index 000000000..3d6afaee3 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/Search.kt @@ -0,0 +1,24 @@ +package org.mozilla.fenix.components + +import android.content.Context +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import mozilla.components.browser.search.SearchEngineManager + + +/** + * Component group for all search engine integration related functionality. + */ +class Search(private val context: Context) { + + /** + * This component provides access to a centralized registry of search engines. + */ + val searchEngineManager by lazy { + SearchEngineManager().apply { + GlobalScope.launch { + load(context).await() + } + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/components/UseCases.kt b/app/src/main/java/org/mozilla/fenix/components/UseCases.kt new file mode 100644 index 000000000..95b12c96e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/UseCases.kt @@ -0,0 +1,21 @@ +package org.mozilla.fenix.components + +import android.content.Context +import mozilla.components.browser.search.SearchEngineManager +import mozilla.components.browser.session.SessionManager +import mozilla.components.feature.search.SearchUseCases +import mozilla.components.feature.session.SessionUseCases + +/** + * Component group for all use cases. Use cases are provided by feature + * modules and can be triggered by UI interactions. + */ +class UseCases( + private val context: Context, + private val sessionManager: SessionManager, + private val searchEngineManager: SearchEngineManager +) { + + val searchUseCases by lazy { SearchUseCases(context, searchEngineManager, sessionManager) } + val sessionUseCases by lazy { SessionUseCases(sessionManager) } +} diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt new file mode 100644 index 000000000..cea12751b --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt @@ -0,0 +1,42 @@ +package org.mozilla.fenix.components.toolbar + +import android.content.Context +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import mozilla.components.browser.domains.autocomplete.DomainAutocompleteProvider +import mozilla.components.browser.toolbar.BrowserToolbar +import mozilla.components.feature.toolbar.ToolbarAutocompleteFeature +import mozilla.components.feature.toolbar.ToolbarFeature +import org.mozilla.fenix.ext.components + +class ToolbarIntegration( + context: Context, + toolbar: BrowserToolbar, + domainAutocompleteProvider: DomainAutocompleteProvider, + sessionId: String? = null +) : LifecycleObserver { + init { + ToolbarAutocompleteFeature(toolbar).apply { + addDomainProvider(domainAutocompleteProvider) + } + } + + private val toolbarFeature: ToolbarFeature = ToolbarFeature( + toolbar, + context.components.core.sessionManager, + context.components.useCases.sessionUseCases.loadUrl, + { searchTerms -> context.components.useCases.searchUseCases.defaultSearch.invoke(searchTerms) }, + sessionId + ) + + @OnLifecycleEvent(Lifecycle.Event.ON_START) + fun start() { + toolbarFeature.start() + } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + fun stop() { + toolbarFeature.stop() + } +} diff --git a/app/src/main/java/org/mozilla/fenix/ext/Context.kt b/app/src/main/java/org/mozilla/fenix/ext/Context.kt new file mode 100644 index 000000000..f1e4a029a --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/ext/Context.kt @@ -0,0 +1,11 @@ +package org.mozilla.fenix.ext + +import android.content.Context +import org.mozilla.fenix.FenixApplication +import org.mozilla.fenix.components.Components + +val Context.application: FenixApplication + get() = applicationContext as FenixApplication + +val Context.components: Components + get() = application.components \ No newline at end of file diff --git a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt new file mode 100644 index 000000000..6ae774e77 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -0,0 +1,7 @@ +package org.mozilla.fenix.ext + +import androidx.fragment.app.Fragment +import org.mozilla.fenix.components.Components + +val Fragment.requireComponents: Components + get() = requireContext().components \ No newline at end of file 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 9f5497e99..fa3cc70f9 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -46,7 +46,7 @@ class HomeFragment : Fragment() { val extras = FragmentNavigator.Extras.Builder().addSharedElement( toolbar, ViewCompat.getTransitionName(toolbar)!! ).build() - Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_browserFragment, null, null, extras) + Navigation.findNavController(it).navigate(R.id.action_homeFragment_to_searchFragment, null, null, extras) } session_list.apply { diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt index 7efa899d6..c33562a28 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt @@ -11,7 +11,9 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import kotlinx.android.synthetic.main.fragment_search.* +import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider import org.mozilla.fenix.R +import org.mozilla.fenix.components.toolbar.ToolbarIntegration class SearchFragment : Fragment() { override fun onCreateView( @@ -33,6 +35,15 @@ class SearchFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + lifecycle.addObserver( + ToolbarIntegration( + requireContext(), + toolbar, + ShippedDomainsProvider().also { it.initialize(requireContext()) }, + "1") + ) + toolbar_wrapper.clipToOutline = false toolbar.apply { textColor = ContextCompat.getColor(context, R.color.searchText) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index c49007b04..31b8e0ad9 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -36,6 +36,7 @@ object Deps { 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_domains = "org.mozilla.components:browser-domains:${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}" @@ -43,6 +44,7 @@ object Deps { 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 mozilla_feature_toolbar = "org.mozilla.components:feature-toolbar:${Versions.mozilla_android_components}" const val mozilla_support_ktx = "org.mozilla.components:support-ktx:${Versions.mozilla_android_components}"