From e57aa67d606ac1886c71b2b275da9fbc6fc960be Mon Sep 17 00:00:00 2001 From: Sawyer Blatz Date: Thu, 28 Feb 2019 09:25:37 -0800 Subject: [PATCH] Closes #664 & Closes #665: Refactors load to respect private mode (#667) --- .../java/org/mozilla/fenix/HomeActivity.kt | 51 +++++++++++++++--- .../mozilla/fenix/IntentReceiverActivity.kt | 13 ++++- .../org/mozilla/fenix/components/Utilities.kt | 4 ++ .../components/toolbar/ToolbarComponent.kt | 2 +- .../fenix/components/toolbar/ToolbarUIView.kt | 2 +- .../mozilla/fenix/search/SearchFragment.kt | 53 +++---------------- .../search/awesomebar/AwesomeBarComponent.kt | 11 ++-- .../search/awesomebar/AwesomeBarUIView.kt | 46 +++++++++++----- 8 files changed, 110 insertions(+), 72 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 1c5393962..92a6a008a 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -15,9 +15,12 @@ import androidx.appcompat.widget.Toolbar import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.NavigationUI +import mozilla.components.browser.session.Session import mozilla.components.concept.engine.EngineView import mozilla.components.feature.intent.IntentProcessor import mozilla.components.support.base.feature.BackHandler +import mozilla.components.support.ktx.kotlin.isUrl +import mozilla.components.support.ktx.kotlin.toNormalizedUrl import mozilla.components.support.utils.SafeIntent import org.mozilla.fenix.ext.components @@ -41,17 +44,16 @@ open class HomeActivity : AppCompatActivity() { setContentView(R.layout.activity_home) - if (intent?.extras?.getBoolean(OPEN_TO_BROWSER) == true) { - intent?.putExtra(OPEN_TO_BROWSER, false) - openToBrowser() - } - val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment val hostNavController = host.navController val appBarConfiguration = AppBarConfiguration.Builder(setOf(R.id.libraryFragment)).build() val navigationToolbar = findViewById(R.id.navigationToolbar) setSupportActionBar(navigationToolbar) NavigationUI.setupWithNavController(navigationToolbar, hostNavController, appBarConfiguration) + + if (intent?.extras?.getBoolean(OPEN_TO_BROWSER) == true) { + handleOpenedFromExternalSource() + } } override fun onCreateView( @@ -88,13 +90,48 @@ open class HomeActivity : AppCompatActivity() { } } - private fun openToBrowser() { - val sessionId = SafeIntent(intent).getStringExtra(IntentProcessor.ACTIVE_SESSION_ID) + private fun handleOpenedFromExternalSource() { + intent?.putExtra(OPEN_TO_BROWSER, false) + openToBrowser(SafeIntent(intent).getStringExtra(IntentProcessor.ACTIVE_SESSION_ID)) + } + + // Since we must always call load after navigation, we only directly expose the load when coupled with open. + fun openToBrowserAndLoad(text: String, sessionId: String? = null) { + openToBrowser(sessionId) + load(text, sessionId) + } + + fun openToBrowser(sessionId: String?) { val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment val directions = NavGraphDirections.actionGlobalBrowser(sessionId) host.navController.navigate(directions) } + private fun load(text: String, sessionId: String?) { + val isPrivate = this.browsingModeManager.isPrivate + + val loadUrlUseCase = if (sessionId == null) { + if (isPrivate) { + components.useCases.tabsUseCases.addPrivateTab + } else { + components.useCases.tabsUseCases.addTab + } + } else components.useCases.sessionUseCases.loadUrl + + val searchUseCase: (String) -> Unit = { searchTerms -> + if (sessionId == null) { + components.useCases.searchUseCases.newTabSearch + .invoke(searchTerms, Session.Source.USER_ENTERED, true, isPrivate) + } else components.useCases.searchUseCases.defaultSearch.invoke(searchTerms) + } + + if (text.isUrl()) { + loadUrlUseCase.invoke(text.toNormalizedUrl()) + } else { + searchUseCase.invoke(text) + } + } + companion object { const val OPEN_TO_BROWSER = "open_to_browser" } diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index 907c34adb..d82e2c573 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix import android.app.Activity import android.content.Intent import android.os.Bundle +import android.preference.PreferenceManager import mozilla.components.browser.session.tab.CustomTabConfig import mozilla.components.support.utils.SafeIntent import org.mozilla.fenix.customtabs.CustomTabActivity @@ -17,8 +18,16 @@ class IntentReceiverActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - components.utils.intentProcessor.process(intent) - var openToBrowser = false + val isPrivate = PreferenceManager + .getDefaultSharedPreferences(this).getBoolean(getString(R.string.pref_key_private_mode), false) + + if (isPrivate) { + components.utils.privateIntentProcessor.process(intent) + } else { + components.utils.intentProcessor.process(intent) + } + + val openToBrowser: Boolean val intent = Intent(intent) openToBrowser = when { diff --git a/app/src/main/java/org/mozilla/fenix/components/Utilities.kt b/app/src/main/java/org/mozilla/fenix/components/Utilities.kt index 40438e9f3..4d29116b4 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Utilities.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Utilities.kt @@ -26,4 +26,8 @@ class Utilities( val intentProcessor by lazy { IntentProcessor(sessionUseCases, sessionManager, searchUseCases, context) } + + val privateIntentProcessor by lazy { + IntentProcessor(sessionUseCases, sessionManager, searchUseCases, context, isPrivate = true) + } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt index 82d6bdee9..231a86ad4 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarComponent.kt @@ -54,7 +54,7 @@ class ToolbarComponent( data class SearchState(val query: String, val isEditing: Boolean) : ViewState sealed class SearchAction : Action { - data class UrlCommitted(val url: String) : SearchAction() + data class UrlCommitted(val url: String, val session: String?) : SearchAction() data class TextChanged(val query: String) : SearchAction() object ToolbarTapped : SearchAction() data class ToolbarMenuItemTapped(val item: ToolbarMenu.Item) : SearchAction() diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt index 75939c7f9..2420a9caa 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt @@ -38,7 +38,7 @@ class ToolbarUIView( init { view.apply { setOnUrlCommitListener { - actionEmitter.onNext(SearchAction.UrlCommitted(it)) + actionEmitter.onNext(SearchAction.UrlCommitted(it, sessionId)) false } onUrlClicked = { 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 fec3171f9..726a733c2 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt @@ -10,11 +10,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import androidx.navigation.Navigation import kotlinx.android.synthetic.main.fragment_search.view.* -import mozilla.components.browser.session.Session -import mozilla.components.support.ktx.kotlin.isUrl -import mozilla.components.support.ktx.kotlin.toNormalizedUrl import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.toolbar.SearchAction @@ -57,7 +53,7 @@ class SearchFragment : Fragment() { ) awesomeBarComponent = AwesomeBarComponent( view.search_layout, ActionBusFactory.get(this), - AwesomeBarState("", sessionId == null) + AwesomeBarState("", sessionId == null, isPrivate) ) ActionBusFactory.get(this).logMergedObservables() return view @@ -85,8 +81,7 @@ class SearchFragment : Fragment() { when (it) { is SearchAction.UrlCommitted -> { if (it.url.isNotBlank()) { - transitionToBrowser() - load(it.url) + (activity as HomeActivity).openToBrowserAndLoad(it.url, it.session) } } is SearchAction.TextChanged -> { @@ -98,46 +93,12 @@ class SearchFragment : Fragment() { getAutoDisposeObservable() .subscribe { when (it) { - is AwesomeBarAction.ItemSelected -> transitionToBrowser() + is AwesomeBarAction.ItemSelected -> { + requireComponents.core.sessionManager.selectedSession?.let { session -> + (activity as HomeActivity).openToBrowser(session.id) + } + } } } } - - // Issue: https://github.com/mozilla-mobile/fenix/issues/626 - // Currently we were kind of forcing all this logic through the Toolbar Feature. - // But since we cannot actually load a page without an available GeckoSession - // we have to wait until after we navigate to call the use case. - // We should move this logic into a place that makes more sense. - private fun load(text: String) { - val sessionId = SearchFragmentArgs.fromBundle(arguments!!).sessionId - val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate - - val loadUrlUseCase = if (sessionId == null) { - if (isPrivate) { - requireComponents.useCases.tabsUseCases.addPrivateTab - } else { - requireComponents.useCases.tabsUseCases.addTab - } - } else requireComponents.useCases.sessionUseCases.loadUrl - - val searchUseCase: (String) -> Unit = { searchTerms -> - if (sessionId == null) { - requireComponents.useCases.searchUseCases.newTabSearch - .invoke(searchTerms, Session.Source.USER_ENTERED, true, isPrivate) - } else requireComponents.useCases.searchUseCases.defaultSearch.invoke(searchTerms) - } - - if (text.isUrl()) { - loadUrlUseCase.invoke(text.toNormalizedUrl()) - } else { - searchUseCase.invoke(text) - } - } - - private fun transitionToBrowser() { - val sessionId = SearchFragmentArgs.fromBundle(arguments!!).sessionId - val directions = SearchFragmentDirections.actionSearchFragmentToBrowserFragment(sessionId) - - Navigation.findNavController(view!!.search_layout).navigate(directions) - } } diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarComponent.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarComponent.kt index 4c68041b3..d24092ea7 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarComponent.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarComponent.kt @@ -11,7 +11,7 @@ import org.mozilla.fenix.mvi.Reducer import org.mozilla.fenix.mvi.UIComponent import org.mozilla.fenix.mvi.ViewState -data class AwesomeBarState(val query: String, val useNewTab: Boolean = false) : ViewState +data class AwesomeBarState(val query: String, val useNewTab: Boolean = false, val isPrivate: Boolean) : ViewState sealed class AwesomeBarAction : Action { object ItemSelected : AwesomeBarAction() @@ -24,7 +24,7 @@ sealed class AwesomeBarChange : Change { class AwesomeBarComponent( private val container: ViewGroup, bus: ActionBusFactory, - override var initialState: AwesomeBarState = AwesomeBarState("") + override var initialState: AwesomeBarState = AwesomeBarState("", isPrivate = false) ) : UIComponent( bus.getManagedEmitter(AwesomeBarAction::class.java), bus.getSafeManagedObservable(AwesomeBarChange::class.java) @@ -35,7 +35,12 @@ class AwesomeBarComponent( } } - override fun initView() = AwesomeBarUIView(initialState.useNewTab, container, actionEmitter, changesObservable) + override fun initView() = AwesomeBarUIView( + initialState.useNewTab, + initialState.isPrivate, + container, + actionEmitter, + changesObservable) init { render(reducer) diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarUIView.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarUIView.kt index 1702cbb61..a111969e2 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarUIView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarUIView.kt @@ -3,6 +3,7 @@ package org.mozilla.fenix.search.awesomebar 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/. */ +import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import io.reactivex.Observable @@ -13,6 +14,9 @@ import mozilla.components.feature.awesomebar.provider.ClipboardSuggestionProvide import mozilla.components.feature.awesomebar.provider.HistoryStorageSuggestionProvider import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider import mozilla.components.feature.awesomebar.provider.SessionSuggestionProvider +import mozilla.components.feature.search.SearchUseCases +import mozilla.components.feature.session.SessionUseCases +import mozilla.components.feature.toolbar.SearchUseCase import mozilla.components.support.ktx.android.graphics.drawable.toBitmap import org.mozilla.fenix.R import org.mozilla.fenix.ext.components @@ -20,6 +24,7 @@ import org.mozilla.fenix.mvi.UIView class AwesomeBarUIView( useNewTab: Boolean, + isPrivate: Boolean, container: ViewGroup, actionEmitter: Observer, changesObservable: Observable @@ -33,11 +38,7 @@ class AwesomeBarUIView( with(container.context) { view.addProviders(ClipboardSuggestionProvider( this, - if (useNewTab) { - components.useCases.tabsUseCases.addTab - } else { - components.useCases.sessionUseCases.loadUrl - }, + getSessionUseCase(this, isPrivate, useNewTab), getDrawable(R.drawable.ic_link).toBitmap(), getString(R.string.awesomebar_clipboard_title) ) @@ -50,15 +51,10 @@ class AwesomeBarUIView( ), HistoryStorageSuggestionProvider( components.core.historyStorage, - if (useNewTab) { - components.useCases.tabsUseCases.addTab - } else components.useCases.sessionUseCases.loadUrl - ), + getSessionUseCase(this, isPrivate, useNewTab)), SearchSuggestionProvider( components.search.searchEngineManager.getDefaultSearchEngine(this), - if (useNewTab) { - components.useCases.searchUseCases.newTabSearch - } else components.useCases.searchUseCases.defaultSearch, + getSearchUseCase(this, isPrivate, useNewTab), components.core.client, SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS ) @@ -68,6 +64,32 @@ class AwesomeBarUIView( view.setOnStopListener { actionEmitter.onNext(AwesomeBarAction.ItemSelected) } } + private fun getSearchUseCase( + context: Context, + isPrivate: Boolean, + useNewTab: Boolean + ): SearchUseCases.SearchUseCase { + if (!useNewTab) { + return context.components.useCases.searchUseCases.defaultSearch + } + + return when (isPrivate) { + true -> context.components.useCases.searchUseCases.newPrivateTabSearch + false -> context.components.useCases.searchUseCases.newTabSearch + } + } + + private fun getSessionUseCase(context: Context, isPrivate: Boolean, useNewTab: Boolean): + SessionUseCases.LoadUrlUseCase { + if (!useNewTab) { + return context.components.useCases.sessionUseCases.loadUrl + } + + return when (isPrivate) { + true -> context.components.useCases.tabsUseCases.addPrivateTab + false -> context.components.useCases.tabsUseCases.addTab + } + } override fun updateView() = Consumer { view.onInputChanged(it.query) }