For #17800 - Request desktop site from home screen. (#18653)

upstream-sync
Mihai Adrian Carare 3 years ago committed by GitHub
parent caf8ac8207
commit ccfb275b03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,6 +40,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
import mozilla.components.browser.state.state.SessionState
@ -122,7 +123,7 @@ import java.lang.ref.WeakReference
* - browser screen
*/
@OptIn(ExperimentalCoroutinesApi::class)
@SuppressWarnings("TooManyFunctions", "LargeClass")
@SuppressWarnings("TooManyFunctions", "LargeClass", "LongParameterList")
open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
// DO NOT MOVE ANYTHING ABOVE THIS, GETTING INIT TIME IS CRITICAL
// we need to store startup timestamp for warm startup. we cant directly store
@ -747,10 +748,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
customTabSessionId: String? = null,
engine: SearchEngine? = null,
forceSearch: Boolean = false,
flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none()
flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(),
requestDesktopMode: Boolean = false
) {
openToBrowser(from, customTabSessionId)
load(searchTermOrURL, newTab, engine, forceSearch, flags)
load(searchTermOrURL, newTab, engine, forceSearch, flags, requestDesktopMode)
}
fun openToBrowser(from: BrowserDirection, customTabSessionId: String? = null) {
@ -816,7 +818,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
newTab: Boolean,
engine: SearchEngine?,
forceSearch: Boolean,
flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none()
flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(),
requestDesktopMode: Boolean = false
) {
val startTime = components.core.engine.profiler?.getProfilerTime()
val mode = browsingModeManager.mode
@ -833,6 +836,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
// and let it try to load whatever was entered.
if ((!forceSearch && searchTermOrURL.isUrl()) || engine == null) {
loadUrlUseCase.invoke(searchTermOrURL.toNormalizedUrl(), flags)
if (requestDesktopMode) {
handleRequestDesktopMode()
}
} else {
if (newTab) {
components.useCases.searchUseCases.newTabSearch
@ -859,6 +866,19 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
}
internal fun handleRequestDesktopMode() {
val requestDesktopSiteUseCase =
components.useCases.sessionUseCases.requestDesktopSite
requestDesktopSiteUseCase.invoke(true)
components.core.store.dispatch(
ContentAction.UpdateDesktopModeAction(
components.core.store.state.selectedTabId.toString(), true
)
)
// Reset preference value after opening the tab in desktop mode
settings().openNextTabInDesktopMode = false
}
open fun navigateToBrowserOnColdStart() {
// Normal tabs + cold start -> Should go back to browser if we had any tabs open when we left last
// except for PBM + Cold Start there won't be any tabs since they're evicted so we never will navigate

@ -252,6 +252,7 @@ class HomeFragment : Fragment() {
restoreUseCase = components.useCases.tabsUseCases.restore,
reloadUrlUseCase = components.useCases.sessionUseCases.reload,
selectTabUseCase = components.useCases.tabsUseCases.selectTab,
requestDesktopSiteUseCase = components.useCases.sessionUseCases.requestDesktopSite,
fragmentStore = homeFragmentStore,
navController = findNavController(),
viewLifecycleScope = viewLifecycleOwner.lifecycleScope,
@ -854,6 +855,9 @@ class HomeFragment : Fragment() {
HomeFragmentDirections.actionGlobalAddonsManagementFragment()
)
}
is HomeMenu.Item.DesktopMode -> {
context.settings().openNextTabInDesktopMode = it.checked
}
}
},
onHighlightPresent = { menuButtonView.get()?.setHighlight(it) },

@ -16,6 +16,7 @@ import mozilla.components.browser.menu.BrowserMenuHighlight
import mozilla.components.browser.menu.ext.getHighlight
import mozilla.components.browser.menu.item.BrowserMenuDivider
import mozilla.components.browser.menu.item.BrowserMenuHighlightableItem
import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType
@ -48,6 +49,7 @@ class HomeMenu(
object Downloads : Item()
object Quit : Item()
object Sync : Item()
data class DesktopMode(val checked: Boolean) : Item()
}
private val primaryTextColor =
@ -176,6 +178,14 @@ class HomeMenu(
onItemTapped.invoke(Item.Downloads)
}
val desktopItem = BrowserMenuImageSwitch(
imageResource = R.drawable.ic_desktop,
label = context.getString(R.string.browser_menu_desktop_site),
initialState = { context.settings().openNextTabInDesktopMode }
) { checked ->
onItemTapped.invoke(Item.DesktopMode(checked))
}
// Only query account manager if it has been initialized.
// We don't want to cause its initialization just for this check.
val accountAuthItem = if (context.components.backgroundServices.accountManagerAvailableQueue.isReady()) {
@ -193,6 +203,9 @@ class HomeMenu(
syncedTabsItem,
bookmarksItem,
historyItem,
BrowserMenuDivider(),
desktopItem,
BrowserMenuDivider(),
downloadsItem,
BrowserMenuDivider(),
addons,

@ -39,6 +39,7 @@ import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeFragment
import org.mozilla.fenix.home.HomeFragmentAction
import org.mozilla.fenix.home.HomeFragmentDirections
@ -181,6 +182,7 @@ class DefaultSessionControlController(
private val restoreUseCase: TabsUseCases.RestoreUseCase,
private val reloadUrlUseCase: SessionUseCases.ReloadUrlUseCase,
private val selectTabUseCase: TabsUseCases.SelectTabUseCase,
private val requestDesktopSiteUseCase: SessionUseCases.RequestDesktopSiteUseCase,
private val fragmentStore: HomeFragmentStore,
private val navController: NavController,
private val viewLifecycleScope: CoroutineScope,
@ -403,6 +405,10 @@ class DefaultSessionControlController(
selectTab = true,
startLoading = true
)
if (settings.openNextTabInDesktopMode) {
activity.handleRequestDesktopMode()
}
activity.openToBrowser(BrowserDirection.FromHome)
}

@ -24,6 +24,7 @@ import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.crashes.CrashListActivity
import org.mozilla.fenix.ext.navigateSafe
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.utils.Settings
@ -32,7 +33,7 @@ import org.mozilla.fenix.utils.Settings
*/
@Suppress("TooManyFunctions")
interface SearchController {
fun handleUrlCommitted(url: String)
fun handleUrlCommitted(url: String, fromHomeScreen: Boolean = false)
fun handleEditingCancelled()
fun handleTextChanged(text: String)
fun handleUrlTapped(url: String)
@ -60,7 +61,7 @@ class SearchDialogController(
private val clearToolbar: () -> Unit
) : SearchController {
override fun handleUrlCommitted(url: String) {
override fun handleUrlCommitted(url: String, fromHomeScreen: Boolean) {
when (url) {
"about:crashes" -> {
// The list of past crashes can be accessed via "settings > about", but desktop and
@ -73,16 +74,19 @@ class SearchDialogController(
SearchDialogFragmentDirections.actionGlobalAddonsManagementFragment()
navController.navigateSafe(R.id.searchDialogFragment, directions)
}
"moz://a" -> openSearchOrUrl(SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.MANIFESTO))
"moz://a" -> openSearchOrUrl(
SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.MANIFESTO),
fromHomeScreen
)
else ->
if (url.isNotBlank()) {
openSearchOrUrl(url)
openSearchOrUrl(url, fromHomeScreen)
}
}
dismissDialog()
}
private fun openSearchOrUrl(url: String) {
private fun openSearchOrUrl(url: String, fromHomeScreen: Boolean) {
clearToolbarFocus()
val searchEngine = fragmentStore.state.searchEngineSource.searchEngine
@ -91,7 +95,8 @@ class SearchDialogController(
searchTermOrURL = url,
newTab = fragmentStore.state.tabId == null,
from = BrowserDirection.FromSearchDialog,
engine = searchEngine
engine = searchEngine,
requestDesktopMode = fromHomeScreen && activity.settings().openNextTabInDesktopMode
)
val event = if (url.isUrl() || searchEngine == null) {

@ -168,20 +168,22 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
)
)
val fromHomeFragment =
findNavController().previousBackStackEntry?.destination?.id == R.id.homeFragment
toolbarView = ToolbarView(
requireContext(),
interactor,
historyStorageProvider(),
isPrivate,
view.toolbar,
requireComponents.core.engine
requireComponents.core.engine,
fromHomeFragment
)
val awesomeBar = view.awesome_bar
awesomeBar.customizeForBottomToolbar = requireContext().settings().shouldUseBottomToolbar
val fromHomeFragment =
findNavController().previousBackStackEntry?.destination?.id == R.id.homeFragment
awesomeBarView = AwesomeBarView(
activity,
interactor,

@ -17,8 +17,8 @@ class SearchDialogInteractor(
private val searchController: SearchDialogController
) : AwesomeBarInteractor, ToolbarInteractor {
override fun onUrlCommitted(url: String) {
searchController.handleUrlCommitted(url)
override fun onUrlCommitted(url: String, fromHomeScreen: Boolean) {
searchController.handleUrlCommitted(url, fromHomeScreen)
}
override fun onEditingCanceled() {

@ -31,8 +31,9 @@ interface ToolbarInteractor {
/**
* Called when a user hits the return key while [ToolbarView] has focus.
* @param url the text inside the [ToolbarView] when committed
* @param fromHomeScreen true if the toolbar has been opened from home screen
*/
fun onUrlCommitted(url: String)
fun onUrlCommitted(url: String, fromHomeScreen: Boolean = false)
/**
* Called when a user removes focus from the [ToolbarView]
@ -49,13 +50,15 @@ interface ToolbarInteractor {
/**
* View that contains and configures the BrowserToolbar to only be used in its editing mode.
*/
@Suppress("LongParameterList")
class ToolbarView(
private val context: Context,
private val interactor: ToolbarInteractor,
private val historyStorage: HistoryStorage?,
private val isPrivate: Boolean,
val view: BrowserToolbar,
engine: Engine
engine: Engine,
fromHomeFragment: Boolean
) {
@VisibleForTesting
@ -70,7 +73,7 @@ class ToolbarView(
// from resizing in case the BrowserFragment is being displayed before the
// keyboard is gone: https://github.com/mozilla-mobile/fenix/issues/8399
hideKeyboard()
interactor.onUrlCommitted(it)
interactor.onUrlCommitted(it, fromHomeFragment)
false
}

@ -1020,4 +1020,13 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = false,
featureFlag = FeatureFlags.addressesFeature
)
/**
* Storing desktop item checkbox value in the home screen menu.
* If set to true, next opened tab from home screen will be opened in desktop mode.
*/
var openNextTabInDesktopMode by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_open_next_tab_desktop_mode),
default = false
)
}

@ -257,6 +257,8 @@
<string name="pref_key_return_to_browser" translatable="false">pref_key_return_to_browser</string>
<string name="pref_key_open_next_tab_desktop_mode" translatable="false">pref_key_open_next_tab_desktop_mode</string>
<!-- Secret Info Setting Keys -->
<string name="pref_key_secret_debug_info" translatable="false">pref_key_secret_debug_info</string>
<string name="pref_key_leanplum_user_id" translatable="false">pref_key_leanplum_user_id</string>

@ -140,6 +140,7 @@ class DefaultSessionControlControllerTest {
every { analytics.metrics } returns metrics
val restoreUseCase: TabsUseCases.RestoreUseCase = mockk(relaxed = true)
val requestDesktopSiteUseCase: SessionUseCases.RequestDesktopSiteUseCase = mockk(relaxed = true)
controller = spyk(DefaultSessionControlController(
activity = activity,
@ -152,6 +153,7 @@ class DefaultSessionControlControllerTest {
reloadUrlUseCase = reloadUrlUseCase.reload,
selectTabUseCase = selectTabUseCase.selectTab,
restoreUseCase = restoreUseCase,
requestDesktopSiteUseCase = requestDesktopSiteUseCase,
fragmentStore = fragmentStore,
navController = navController,
viewLifecycleScope = scope,

@ -179,6 +179,7 @@ class ToolbarViewTest {
historyStorage = null,
isPrivate = isPrivate,
view = toolbar,
engine = engine
engine = engine,
fromHomeFragment = false
)
}

Loading…
Cancel
Save